首页 文章

JAXB为Jersey中的JSON序列化注释POJO为每个字段类型返回String

提问于
浏览
6

我正在使用Jersey为服务器组件创建Web服务 . 不幸的是我的JSON响应格式有问题,因为数据总是格式化为字符串 .

我有一个带有不同字段类型的简单JAXB注释POJO:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class JaxbPojo {

    @XmlElement(name = "id_64")
    private Long id;

    @XmlElement(name = "desc")
    private String description;

    private Boolean active;

    // getters and setters
    ..
}

和一个简单的资源,返回传入的对象:

@Path("/jaxb_pojo")
public class JaxbPojoResource {

    @POST
    @Consumes({ MediaType.APPLICATION_JSON })
    @Produces({ MediaType.APPLICATION_JSON })
    public JaxbPojo processBidRequest(JaxbPojo pojo) {
         return pojo;
    }

}

使用以下JSON数据向资源发送请求时,将在资源方法内正确填充该对象 . 但返回的JSON数据的字段类型始终格式化为字符串:

me@host:/tmp $ cat simple_jaxb_pojo 
{"id_64":99,"desc":"simple JAXB POJO","active":true}

me@host:/tmp $ curl -X POST -H "Content-Type: application/json" --data-binary @simple_jaxb_pojo http://localhost/srvr/rest/jaxb_pojo
{"id_64":"99","desc":"simple JAXB POJO","active":"true"}

所有使用过的jar文件(jsr311-api-1.1.1.jar,jersey-core-1.6.jar,jersey-json-1.6.jar,jersey-server-1.6.jar)都直接包含在tomcat / lib路径中 . JAX-RS库通过Maven pom.xml使用,范围为“提供”:

<dependency>
    <groupId>javax.ws.rs</groupId>
    <artifactId>jsr311-api</artifactId>
    <version>1.1.1</version>
    <scope>provided</scope>
</dependency>

我的web.xml看起来像这样:

<servlet>
    <servlet-name>RestServlet</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>com.rest.RestResourcesApplication</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

..

<servlet-mapping>
    <servlet-name>RestServlet</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

我是否遗漏了某些东西,或者我可能必须以一种使用我的POJO类型的方式明确配置Jackson . 我对这个主题相当新,所以我发布了我的每一个信息 . 我希望有人能帮帮忙 .

2 回答

  • 1

    有趣的问题 . 我不确定为什么会这样,但尝试添加:

    <init-param>
            <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
            <param-value>true</param-value>
        </init-param>
    

    到web.xml中的Jersey servlet定义 . 我认为Jersey需要这个来生成JSON,但是当我删除这个init-param时,我看到了你遇到的同样的问题 .

  • 1

    user463324的解决方案很好 . 通常,您可以使用此解决方案将Java对象转换为JSON并返回 . 它基于 Jackson 图书馆 .

    如果您想基于JAXB获取JSON,则提供了一些配置选项,以便您可以控制事物序列化和反序列化的方式 . 对于默认配置,您将获得字符串格式,就像您指出的问题一样 .

    要实现更重要的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 = { JaxbPojo.class};
        public JAXBContextResolver() throws Exception {
            this.types = new HashSet(Arrays.asList(ctypes));
            this.context = new JSONJAXBContext(JSONConfiguration.natural().build(),
                    ctypes);
        }
    
        @Override
        public JAXBContext getContext(Class<?> objectType) {
            return (types.contains(objectType)) ? context : null;
        }
    }
    

    有关详细信息,请参阅jersey' official document .

相关问题