Message body writer for Java class java.util.ArrayList ... and MIME type text / xml not found

I am using Jersey to create a REST service and want to return Collection<String> as XML.

 @GET @Produces(MediaType.TEXT_XML) @Path("/directgroups") public Response getDirectGroupsForUser(@PathParam("userId") String userId) { try { Collection<String> result = service.getDirectGroupsForUser(userId, null, true); // return result; //first try // return result.toArray(new String[0]); //second try return Response.ok().type(MediaType.TEXT_XML).entity(result).build(); //third try } catch (UserServiceException e) { LOGGER.error(e); throw new RuntimeException(e.getMessage()); } } 

but my attempts fail with the following exception:

javax.ws.rs.WebApplicationException: com.sun.jersey.api.MessageException: message body writer for the Java class java.util.ArrayList and Java class class java.util.ArrayList and MIME text type / xml not found

and all the results of this exception that I found through google concerned returning text / json instead of text / xml, as in my situation.

Can anyone help me? I thought that if I use Response, this will be my root element in XML, and my collection is a list of string elements in it.

+13
java rest xml jersey jaxb
source share
4 answers

NOTE. . Although this answer works, anar answer is better.

You should try using the annotated JAXB class to solve your problem. You can change your method as follows:

 @GET @Produces(MediaType.TEXT_XML) @Path("/directgroups") public Groups getDirectGroupsForUser(@PathParam("userId") String userId) { try { Groups groups = new Groups(); groups.getGroup().addAll(service.getDirectGroupsForUser(userId, null, true)); return groups; } catch (UserServiceException e) { LOGGER.error(e); throw new RuntimeException(e.getMessage()); } } 

And then create an annotated JAXB class for your groups. I have included the generated class for you using the process described in this answer . Here is an example of the documents that he will produce:

 <groups> <group>Group1</group> </group>Group2</group> </groups> 

And here is the generated class:

 package example; import java.util.ArrayList; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; /** * <p>Java class for anonymous complex type. * * <p>The following schema fragment specifies the expected content contained within this class. * * <pre> * &lt;complexType> * &lt;complexContent> * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> * &lt;sequence> * &lt;element ref="{}group" maxOccurs="unbounded"/> * &lt;/sequence> * &lt;/restriction> * &lt;/complexContent> * &lt;/complexType> * </pre> * * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { "group" }) @XmlRootElement(name = "groups") public class Groups { @XmlElement(required = true) protected List<String> group; /** * Gets the value of the group property. * * <p> * This accessor method returns a reference to the live list, * not a snapshot. Therefore any modification you make to the * returned list will be present inside the JAXB object. * This is why there is not a <CODE>set</CODE> method for the group property. * * <p> * For example, to add a new item, do as follows: * <pre> * getGroup().add(newItem); * </pre> * * * <p> * Objects of the following type(s) are allowed in the list * {@link String } * * */ public List<String> getGroup() { if (group == null) { group = new ArrayList<String>(); } return this.group; } } 
+11
source share

Using

 List<String> list = new ArrayList<String>(); GenericEntity<List<String>> entity = new GenericEntity<List<String>>(list) {}; Response response = Response.ok(entity).build(); 

The universal object wrapper works to get the result when using the answer builder.

Link

+40
source share

The only thing that has worked for me so far is to create your own Wrapper object.

Don't forget the @XmlRootElement annotation to explain to JAXB how to parse it.

Note that this will work for any type of object - in this example, I used an ArrayList for String.

eg.

The Wrapper object should look like this:

 import java.util.ArrayList; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class ArrayListWrapper { public ArrayList<String> myArray = new ArrayList<String>(); } 

And the REST method should look like this:

 @GET @Produces(MediaType.TEXT_XML) @Path("/directgroups") public ArrayListWrapper getDirectGroupsForUser(@PathParam("userId") String userId) { try { ArrayListWrapper w = new ArrayListWrapper(); w.myArray = service.getDirectGroupsForUser(userId, null, true); return w; } catch (UserServiceException e) { LOGGER.error(e); throw new RuntimeException(e.getMessage()); } } 
0
source share

adding @XmlRootElement (name = "class name") to the object I want to return resolved my problem

0
source share

All Articles