如何在Jersey中获得JSON和XML响应,在两种情况下都有root元素?

时间:2015-04-06 15:02:19

标签: java xml json jersey jax-rs

我希望通过使用单一功能来响应:

@GET
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response getVolume(){
    ...enter code here
    return Response.ok().entity(VolDetail).build();
}

输出应该是:

xml:
<volume>
   <status>available</status>
</volume>

JSON:
{"volume":{"status":"available"}}

其中volume是POJO类。

问题是我没有在JSON中获得root元素。我尝试了JSON对象绑定,但它无法正常工作。

1 个答案:

答案 0 :(得分:1)

假设你正在使用杰克逊。您可以将ObjectMapper配置为WRAP_ROOT_VALUE。你会在ContextResolver中做到这一点。使用Jackson 1.x,它看起来像

import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig.Feature;

@Provider
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper>  {

    final ObjectMapper mapper = new ObjectMapper();

    public ObjectMapperContextResolver() {
        mapper.configure(Feature.WRAP_ROOT_VALUE, true);
    }

    @Override
    public ObjectMapper getContext(Class<?> type) {
        return mapper;
    }  
}

使用Jackson 2.x,它看起来像

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;

@Provider
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper>  {

    final ObjectMapper mapper = new ObjectMapper();

    public ObjectMapperContextResolver() {
        mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
    }

    @Override
    public ObjectMapper getContext(Class<?> type) {
        return mapper;
    }  
}

您的POJO应使用@XmlRootElement(name = "volume")@JsonRootName("volume")

进行注释

如果您不希望包装所有对象,可以为不同的类配置不同的映射器,如seen here

修改

使用上述解决方案,只有@JsonRootName才有效。原因是通过使用我们自己的ObjectMapper,我们覆盖了JAXB注释支持配置的行为。我们可以通过mapper.registerModule(new JaxbAnnotationModule());

明确添加支持