我尝试将Jersey中的字符串列表作为JSON和XML返回。 我认为这将是微不足道的。
我的第一次尝试是写这样的东西
@GET
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Path("/bar")
public List<String> 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<java.lang.String>, and MIME media type application/json was not found
然后我为List
编写了一个包装器StringList@XmlRootElement
public class StringList {
private List<String> data;
public StringList() {
}
public StringList(List<String> data) {
this.data = data;
}
public List<String> getData() {
return data;
}
public void setData(List<String> data) {
this.data = data;
}
}
并将外观修改为
@GET
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Path("/foo")
public StringList stringlist() {
return new StringList(sl());
}
对于包含多于1项的列表非常有用。
{"data":["foo","bar"]}
不幸的是,我得到了一个或零元素的两个意外结果
{"data": "just one"} // for one element i would expect {"data": ["just one"]}
null // for no elements i would expect {"data": []}
我做的事情完全错了吗? 我该如何解决这个问题?
答案 0 :(得分:8)
好的,我可以通过搜索样本来修复它
这确实有效,但它只能用于JSON而不能用于XML
@GET
@Produces({MediaType.APPLICATION_JSON})
@Path("/get")
public JSONArray get() {;
return new JSONArray(dao.getStringList());
}
修复问题,但是还有一种通用方法吗?
答案 1 :(得分:6)
您可以使用javax.ws.rs.core.GenericEntity
:
@GET
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Path("/foo")
public GenericEntity<List<String>> stringlist()
{
List<String> list = Arrays.asList("test", "as");
return new GenericEntity<List<String>>(list) {};
}
答案 2 :(得分:1)
为了说服泽西按照你想要的方式输出列表,你需要提供一个自己的ContextResolver:
@Provider
public class JaxbContentResolver implements ContextResolver<JAXBContext> {
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中添加该类......
答案 3 :(得分:0)
您需要使用备用JSON配置JSONConfiguration.natural()
。
最好使用该备用配置作为提供程序创建自己的ContextResolver
,并告诉它负责哪些类。
我不知道以另一种方式全局使用替代配置的方法。
答案 4 :(得分:0)
除了提供的答案之外,如果您仍然获得MessageBodyWriter not found
,请尝试添加依赖项,例如:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
</dependency>
答案 5 :(得分:0)
我对此的解决方案是一个包装类(在某处找到它)。它现在有效。我不理解不支持javas List类作为根元素的想法。也许它与我不知道的一些json规范/最佳实践有关。
但是现在我正在使用它:
public class Houses {
private List<String> houses;
// Needed for jersey
public Houses() { }
public Houses(List<String> houses) {
this.houses = houses;
}
public void setHouses(List<String> houses) {
this.houses = houses;
}
public List<String> getHouses() {
return this.houses;
}
}