泽西岛:返回一个字符串列表
我尝试将Jersey中的字符串列表作为JSON和XML返回。 我认为这将是微不足道的。
我的第一次尝试是写这样的东西
@GET @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) @Path("/bar") public List get() { return dao.get(); }
我期待一个与此类似的输出:[“string1”,…,“stringN”不幸的是我得到了这个:
com.sun.jersey.api.MessageException: A message body writer for Java class java.util.LinkedList, and Java type java.util.List, and MIME media type application/json was not found
然后我为List编写了一个包装器StringList
@XmlRootElement public class StringList { private List data; public StringList() { } public StringList(List data) { this.data = data; } public List getData() { return data; } public void setData(List data) { this.data = data; } }
并修改了立面
@GET @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) @Path("/foo") public StringList stringlist() { return new StringList(sl()); }
这对于包含更多项目的列表非常有用。
{"data":["foo","bar"]}
不幸的是,我得到了一个或零个元素的两个意外结果
{"data": "just one"} // for one element i would expect {"data": ["just one"]} null // for no elements i would expect {"data": []}
我做了一些完全错误的事吗? 我怎样才能解决这个问题?
你可以使用javax.ws.rs.core.GenericEntity:
@GET @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @Path("/foo") public GenericEntity> stringlist() { List list = Arrays.asList("test", "as"); return new GenericEntity>(list) {}; }
好的,我可以通过搜索样本来修复它
这确实有效,但它只能用于JSON而不能用于XML
@GET @Produces({MediaType.APPLICATION_JSON}) @Path("/get") public JSONArray get() {; return new JSONArray(dao.getStringList()); }
修复问题,但是还有一个通用的方法吗?
为了说服Jersey以你想要的方式输出列表,你需要提供一个自己的ContextResolver:
@Provider public class JaxbContentResolver implements ContextResolver { private Log log = LogFactory.getLog(getClass()); private JAXBContext context; public JaxbContentResolver() throws JAXBException { Class[] types = {StringList.class}; context = new JSONJAXBContext(JSONConfiguration.mapped().rootUnwrapping(true).arrays("data").build(), types); } @Override public JAXBContext getContext(Class> objectType) { log.trace("Entering Test-getContext for type: " + objectType.getSimpleName()); return context; } }
这样,列表将以您希望的方式显示。
注意:此方法的一个缺点是您需要在代码中保留一个额外的位置; 如果你想在REST接口中添加另一个(列表包装器)类,你需要记住转到上面的代码并在ContextResolver中添加该类…
您需要使用备用JSON配置JSONConfiguration.natural()
。
最好使用备用配置作为提供程序创建自己的ContextResolver
,并告诉它负责哪些类。
我不知道以另一种方式全局使用替代配置的方法。
除了提供的答案之外,如果仍然MessageBodyWriter not found
,请尝试添加依赖项,例如:
org.glassfish.jersey.media jersey-media-moxy
我对此的解决方案是一个包装类(在某处找到它)。 它现在有效。 我不理解不支持javas List类作为根元素的想法。 也许它与一些我不知道的json规范/最佳实践有关。
但是现在我使用这个:
public class Houses { private List houses; // Needed for jersey public Houses() { } public Houses(List houses) { this.houses = houses; } public void setHouses(List houses) { this.houses = houses; } public List getHouses() { return this.houses; } }