Skip to content

Explain when and why use Jaxb2RootElementHttpMessageConverter vs MarshallingHttpMessageConverter [SPR-13530] #18107

@spring-projects-issues

Description

@spring-projects-issues

Manuel Jordan opened SPR-13530 and commented

Hello

I have the following configuration:

 @Bean
public MarshallingHttpMessageConverter marshallingMessageConverter() {
    MarshallingHttpMessageConverter converter = new MarshallingHttpMessageConverter();
    converter.setMarshaller(jaxbMarshaller());
    converter.setUnmarshaller(jaxbMarshaller());
    return converter;
}
 @Bean
public Jaxb2Marshaller jaxbMarshaller() {
    Jaxb2Marshaller jaxbMarshaller = new Jaxb2Marshaller();
    jaxbMarshaller.setClassesToBeBound(PersonaXml.class, PersonaCollection.class, GenericCollection.class);
           Map<String, Object> props = new HashMap<>();
    props.put(Marshaller.JAXB_ENCODING,"UTF-8");
    props.put(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    jaxbMarshaller.setMarshallerProperties(props);
        return jaxbMarshaller;
}

It works fine.

Just in case consider that code works around with

@XmlRootElement(name="persona")
@XmlType(propOrder = {"id","nombre","apellido","fecha"})
public class PersonaXml implements Serializable {

	private static final long serialVersionUID = -2236860541513419944L;
	
	private String id;
	private String nombre;
	private String apellido;
	
	private Date fecha;

	public PersonaXml(){

	}

	@XmlElement(name="id")
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	
	@XmlElement(name="nombre")
	public String getNombre() {
		return nombre;
	}
	public void setNombre(String nombre) {
		this.nombre = nombre;
	}
...

and

@XmlRootElement(name="generic-collection")
public class GenericCollection<T> {

	private Collection<T> collection;
	
	public GenericCollection(){
		
	}
	
	public GenericCollection(Collection<T> collection){
		this.collection = collection;
	}
	
	@XmlElement(name="item")
    public Collection<T> getCollection(){
    	return collection;
    }
}

Again all work fine.

Note: I am using JAXB2 annotations how you can see.

It from package:

  • javax.xml.bind.annotation

After to read some documentation I arrived to here
MvcConfiguration.java

Where it shows:

@Override
	public void configureMessageConverters(
			List<HttpMessageConverter<?>> converters) {

		// List is initially empty. Create and configure what we need.
		MappingJacksonHttpMessageConverter jmc = new MappingJacksonHttpMessageConverter();
		jmc.setPrettyPrint(true);
		logger.info("Creating Jackson V1 convertor: "
				+ jmc.getClass().getSimpleName());
		converters.add(jmc);

		Jaxb2RootElementHttpMessageConverter j2 = new Jaxb2RootElementHttpMessageConverter();
		converters.add(j2);
		return;
	}

I can see Paul uses Jaxb2RootElementHttpMessageConverter

My question is how the titles says:

  • Explain when and why use Jaxb2RootElementHttpMessageConverter vs MarshallingHttpMessageConverter

It for the reference documentation and for the API too

Because after to check the current API, I can see in left part where all the classes/interfaces are listed the following too:

  1. Jaxb2CollectionHttpMessageConverter
  2. Jaxb2Marshaller
  3. Jaxb2RootElementHttpMessageConverter

Where I already have used the second, but wondered when use the first and third.

I am confused because my code already uses JABX2 annotations and through
MarshallingHttpMessageConverter + Jaxb2Marshaller I can work in peace.

So again, when use the first and third.

Even more, in this other JIRA/post:
Jaxb2RootElementHttpMessageConverter doesn't work well with class with @XmlAnyElement

Rossen Stoyanchev says: "Have you considered using MarshallingHttpMessageConverter? It seems to match the behavior you want."

Note: BTW I don't have explicitly declared JAXB2 how a dependency on my build.gradle file. Just Jackson 2. And all work fine.


Affects: 4.2 GA, 4.2.1

Referenced from: commits da707c1

0 votes, 6 watchers

Metadata

Metadata

Assignees

Labels

in: dataIssues in data modules (jdbc, orm, oxm, tx)type: documentationA documentation task

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions