空列表的泽西响应为空而不是{}

时间:2012-10-19 20:45:12

标签: rest jersey

我使用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

UPDATE2: 除了下面的解决方案,由于我使用的是Application for configuration(在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;
    }   
}

3 个答案:

答案 0 :(得分:4)

要实现更重要的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

答案 1 :(得分:2)

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

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

它在正文中返回“{}”。我的restkit客户端现在很高兴。

答案 2 :(得分:0)

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