未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> * <complexType> * <complexContent> * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> * <sequence> * <element ref="{}group" maxOccurs="unbounded"/> * </sequence> * </restriction> * </complexContent> * </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()); } }