【问题标题】:Jersey response for empty list is null instead of {}Jersey 对空列表的响应是 null 而不是 {}
【发布时间】:2012-10-19 20:45:11
【问题描述】:

我有一个使用 Jersey 的 JAX-RS REST 服务。我使用 JAXB 进行 JSON 编组(即@XmlRootElement) 其中一个方法返回使用 JPA 持久化的对象列表。

当此列表包含条目时,它会按我的预期工作。示例:

{"androidDevice":[{"email":"dagfinn.parnas@d2.no","timeCreated":"2012-10-19T
22:41:26.862+02:00"},{"email":"dagfinn.parnas@d1.com","timeCreated":"2012-10-
19T22:41:38.093+02:00"}]}

但是,如果列表为空(或 null),我希望它返回 {}。

相反,它返回 null。示例:

$ curl  -i -H "Accept: application/json" http://....
HTTP/1.1 200 OK
Content-Type: application/json

null

这里是代码

    @GET
@Produces( { MediaType.APPLICATION_JSON ,  MediaType.APPLICATION_XML})
public List<AndroidDevice> getAndroidDevices() {
    logger.info("getAndroidDevices method called");


    EntityManager entityManager = entityMangerFactory.createEntityManager();  
    List<AndroidDevice> resultList = entityManager.createNamedQuery(AndroidDevice.QUERY_ALL_ENTRIES,  
            AndroidDevice.class).getResultList();  

    //avoid returning content null. (doesn't work)
    if(resultList==null){
        resultList=new ArrayList<AndroidDevice>();
    }

    return resultList;
}

有没有办法让 Jersey 返回一个空的 JSON 列表(除了硬编码一个 ResponseBuilder)?

我应该为此类事件提供不同的响应代码吗?

更新:通过 twitter 获得有关此错误报告的提示,该报告的结论是他们不会修复它http://java.net/jira/browse/JERSEY-339

更新2: 除了下面的解决方案之外,由于我使用的是应用程序进行配置(在 web.xml 中引用),因此我必须在此处手动添加 Provider 类。这是相关代码。

public class JAXRSApplication extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> set = new HashSet<Class<?>>();
        //Add all endpoints to this set
        set.add(AndroidDeviceEndpoint.class);
        //Add Providers
        set.add(JAXBContextResolver.class);
        return set;
    }   
}

【问题讨论】:

  • 您如何将内容编组为 JSON? Jersey 只是信使,它被告知发送 null。

标签: rest jersey


【解决方案1】:

要实现更重要的 JSON 格式更改,您需要配置 Jersey JSON 处理器本身。可以在 JSONConfiguration 实例上设置各种配置选项。然后可以进一步使用该实例来创建 JSONConfigurated JSONJAXBContext,作为该区域的主要配置点。要将您的专用 JSONJAXBContext 传递给 Jersey,您最终需要实现一个 JAXBContext ContextResolver:

@Provider
public class JAXBContextResolver implements ContextResolver<JAXBContext> {
    private final JAXBContext context;
    private final Set<Class> types;
    private Class[] ctypes = { AndroidDevice.class}; //your pojo class
    public JAXBContextResolver() throws Exception {
        this.types = new HashSet(Arrays.asList(ctypes));
        this.context = new JSONJAXBContext(JSONConfiguration.natural().build(),
                ctypes); //json configuration
    }

    @Override
    public JAXBContext getContext(Class<?> objectType) {
        return (types.contains(objectType)) ? context : null;
    }
}

详情请参阅jersey official document

【讨论】:

  • Ref java.net/jira/browse/JERSEY-339,您认为这会有所帮助吗(似乎与它无关)
  • 你用的是什么球衣版本?我使用的是 1.11 版。使用 natural() 配置,我将得到 [] 作为空列表。使用默认配置,我会为空列表获得 null。
  • 使用 1.14 版。 JAXBContextREsolver 如何附加到泽西岛(在战争项目中)?尝试添加类,但假设我必须在 web.xml 中配置一些东西
  • 不需要任何配置,只要使用@Provider,jersey就可以找到并注册。
  • 尝试什么都不做并调试,但从未调用 JAXBContextResolver 构造函数。从 web.xml 我指的是一个应用程序(参考示例 2.11 jersey.java.net/nonav/documentation/latest/… ),这可以解释为什么它没有被拾取(需要应用程序,因为在以后的球衣版本中发生了变化)。 jersey.java.net/nonav/documentation/latest/… 并没有真正为我提供更多信息,它说要在客户端进行设置,但据我所知,在我的设置中,CURL 是客户端
【解决方案2】:

当 RESTful 服务返回 null 时,我遇到了同样的问题。我所做的只是检查列表大小。如果列表的大小为 0,我使用以下内容:

return Response.ok("{}", req.getContentType()).status(Response.Status.OK); 

它在正文中返回“{}”。我的 restkit 客户现在对此很满意。

【讨论】:

  • 这个解决方案可能被认为是比使用com.sun.jersey.api.json包更好的解决方案。
【解决方案3】:

我遇到了同样的问题。在 Jersey 1.09 中,一个空数组被发送为null,而一个填充的数组被正确写入。现在我使用 Jersey 1.19.4,在这个版本中,一个空数组被正确写入为{}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-08
    • 2012-08-10
    • 1970-01-01
    相关资源
    最近更新 更多