未findJava类java.util.ArrayList …和MIME媒体typestext / xml的消息正文编写器

我使用Jersey来构build一个REST服务,并希望返回一个Collection<String>作为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()); } } 

但我的尝试失败,有以下例外:

javax.ws.rs.WebApplicationException:com.sun.jersey.api.MessageException:Java类java.util.ArrayList的消息主体编写器,Java类类java.util.ArrayList和MIME媒体typestext / xml不是发现

和所有的结果,我发现通过谷歌处理返回的文本/ JSON而不是像我的情况下的文本/ XML的exception。

任何人都可以帮我吗? 我想,如果我使用一个响应,这将是我在XML的根元素和我的集合中的string元素的列表..

注意:虽然这个答案有效, 但是anar的答案是更好的。

您应该尝试使用JAXB注释类来解决您的问题。 你可以改变你的方法:

 @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()); } } 

然后为您的组创build一个JAXB注释类。 我已经包含了一个生成的类,使用这个答案中描述的过程。 以下是它将生成的文档的一个示例:

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

这里是生成的类:

 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; } } 

使用

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

通用实体包装器在使用“响应”构build器时可以获得输出。

参考 – http://jackson.codehaus.org/javadoc/jax-rs/1.0/javax/ws/rs/core/GenericEntity.html

到目前为止,我唯一的工作就是创build我自己的Wrapper对象。

不要忘记@XmlRootElement注释来解释JAXB如何parsing它。

请注意,这将适用于任何types的对象 – 在这个例子中我使用了String的ArrayList。

例如

包装对象应该看起来像这样:

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

而REST方法应该是这样的:

 @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()); } }