泽西岛:返回一个字符串列表

我尝试将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; } }