空列表的Jersey响应为null而不是{} [英] Jersey response for empty list is null instead of {}

查看:99
本文介绍了空列表的Jersey响应为null而不是{}的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a JAX-RS REST service using Jersey. I use JAXB for JSON marshalling (ie. @XmlRootElement) One of the method returns a list of objects persisted with JPA.

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

When this list contains entries it works as I expect. Example:

{"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),我希望它返回{}.

However, if the list is empty (or null) I would expect it to return {}.

相反,它返回null.示例:

Instead it returns null. Example:

$ 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进行硬编码之外)?

Is there any way to get Jersey to return an empty JSON list (besides hardcoding a ResponseBuilder) ?

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

Should I instead provide a different response code for such events?

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

Update: Got a tips through twitter about this bug report which concludes with that they won't fix it http://java.net/jira/browse/JERSEY-339

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

Update2: In addition to the solution below, since I was using an Application for configuration (refered to in web.xml), I had to manually add the Provider class there. Here is the relevant code.

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 JSON处理器本身.可以在JSONConfiguration实例上设置各种配置选项.然后,该实例可以进一步用于创建JSONConfigurated JSONJAXBContext,它用作该区域中的主要配置点.要将专业的JSONJAXBContext传递给Jersey,最终将需要实现JAXBContext ContextResolver:

To achieve more important JSON format changes, you will need to configure Jersey JSON procesor itself. Various configuration options could be set on an JSONConfiguration instance. The instance could be then further used to create a JSONConfigurated JSONJAXBContext, which serves as a main configuration point in this area. To pass your specialized JSONJAXBContext to Jersey, you will finally need to implement a 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;
    }
}

有关详细信息,请参考球衣官方文档.

refer to jersey official document for detailed information.

这篇关于空列表的Jersey响应为null而不是{}的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆