Jersey 2.0 相当于 POJOMappingFeature

Posted

技术标签:

【中文标题】Jersey 2.0 相当于 POJOMappingFeature【英文标题】:Jersey 2.0 equivalent to POJOMappingFeature 【发布时间】:2013-07-08 06:06:40 【问题描述】:

我有一些使用 Jersey

我现在在尝试配置 Moxy 时苦苦挣扎,它的接缝似乎比添加的要复杂得多

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

回到 Jersey

是否有可能只说“请添加 json 支持”?

目前我只是收到很多内部服务器错误错误,而服务器上没有任何日志条目,只是想“我必须做一些完全错误的事情,这不会那么难”

谁能给我一个提示?

【问题讨论】:

这是使用 MOXy 和 JSON 的 Jersey 示例:github.com/jersey/jersey/tree/master/examples/json-moxy 这是描述如何配置 Jersey 和 MOXy 以支持 JSON 的 Jersey 用户指南:jersey.github.io/documentation/latest/media.html#json.moxy 【参考方案1】:

请使用以下依赖项,它会自动为您完成。

 <dependency>
        <groupId>com.fasterxml.jackson.jaxrs</groupId>
        <artifactId>jackson-jaxrs-json-provider</artifactId>
        <version>2.2.3</version>
   </dependency>

【讨论】:

这是最简单的方法。 AFAIK,Jackson 是 JSON Web 服务输出的事实上的行业标准。 谷歌搜索这个依赖会导致一个弃用的 github 存储库,它本身会导致一个更新的 github 存储库,具有不同的依赖项名称:github.com/FasterXML/jackson-jaxrs-providers 这是正确答案! “jersey-media-json-jackson”神器错误地包含了jackskon 1.9 jar 库! 我也遇到了 MOXy 的问题(这要求我的 bean 作为 JSON 以具有空的构造函数,这似乎是因为其内部使用了 JAXB)。删除 MOXy 作为依赖项并添加它解决了我的问题。【参考方案2】:

如果你想在你的 web.xml 文件中定义它,那么:

杰克逊:

<init-param>
  <param-name>jersey.config.server.provider.classnames</param-name>
  <param-value>org.glassfish.jersey.jackson.JacksonFeature</param-value>
</init-param>

莫西

<init-param>
  <param-name>jersey.config.server.provider.classnames</param-name>
  <param-value>org.glassfish.jersey.moxy.json.MoxyFeature</param-value>
</init-param>

如果使用 maven,请将以下依赖项添加到您的 pom 文件中

杰克逊

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>your jersey version</version>
</dependency>

莫西

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-moxy</artifactId>
    <version>your jersey version</version>
</dependency>

【讨论】:

谢谢!我不明白为什么这不在他们文档的 jersey json 迁移部分:jersey.java.net/documentation/latest/… 只添加 JSONFeature 类如何工作?如果不指定 JaxbAnnotationInterpreter,jersey 如何判断是否应该读取 pojo 类上的 xml 注释?【参考方案3】:

您可以通过 JAX-RS Application 类配置 MOXyJsonProvider 类,将 EclipseLink MOXy 配置为 JSON 绑定提供程序。

示例 #1

package org.example;

import java.util.*;
import javax.ws.rs.core.Application;
import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;

public class CustomerApplication  extends Application 

    @Override
    public Set<Class<?>> getClasses() 
        HashSet<Class<?>> set = new HashSet<Class<?>>(2);
        set.add(MOXyJsonProvider.class);
        set.add(CustomerService.class);
        return set;
    


示例 #2

package org.example;

import java.util.*;
import javax.ws.rs.core.Application;
import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;

public class CustomerApplication  extends Application 

    @Override
    public Set<Class<?>> getClasses() 
        HashSet<Class<?>> set = new HashSet<Class<?>>(1);
        set.add(ExampleService.class);
        return set;
    

    @Override
    public Set<Object> getSingletons() 
        MOXyJsonProvider moxyJsonProvider = new MOXyJsonProvider();

        moxyJsonProvider.setAttributePrefix("@");
        moxyJsonProvider.setFormattedOutput(true);
        moxyJsonProvider.setIncludeRoot(true);
        moxyJsonProvider.setMarshalEmptyCollections(false);
        moxyJsonProvider.setValueWrapper("$");

        Map<String, String> namespacePrefixMapper = new HashMap<String, String>(1);
        namespacePrefixMapper.put("http://www.example.org/customer", "cust");
        moxyJsonProvider.setNamespacePrefixMapper(namespacePrefixMapper);
        moxyJsonProvider.setNamespaceSeparator(':');

        HashSet<Object> set = new HashSet<Object>(1);
        set.add(moxyJsonProvider);
        return set;
    

 

更多信息

http://blog.bdoughan.com/2012/05/moxy-as-your-jax-rs-json-provider.html http://blog.bdoughan.com/2013/06/moxy-is-new-default-json-binding.html

【讨论】:

那么不写代码就不能在2.0中启用json支持吗?【参考方案4】:

实际上,它只对我有用,省略了 PojoMappingFeature 参数。

前往:

http://localhost:8080/webapi/myresource/complexObject/foo

产生这个 json:

"name":"foo","value1":1374185178829,"value2":42

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!-- This web.xml file is not required when using Servlet 3.0 container,
     see implementation details http://jersey.java.net/nonav/documentation/latest/jax-rs.html -->
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <servlet>
        <servlet-name>Jersey Web Application</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>com.example</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Jersey Web Application</servlet-name>
        <url-pattern>/webapi/*</url-pattern>
    </servlet-mapping>
</web-app>

入口点:

package com.example;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

/**
 * Root resource (exposed at "myresource" path)
 */
@Path("myresource")
public class MyResource 

    /**
     * Method handling HTTP GET requests. The returned object will be sent
     * to the client as "text/plain" media type.
     *
     * @return String that will be returned as a text/plain response.
     */
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String getIt() 
        return "Got it!";
    

    @Path( "complexObject/name" )
    @GET
    @Produces(  MediaType.APPLICATION_JSON  )
    public ComplexObject complexObject( @PathParam( "name" ) String name ) 
        return new ComplexObject(name, System.currentTimeMillis(), 42L);
    

bean 到 jsonize:

package com.example;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

/**
 * Root resource (exposed at "myresource" path)
 */
@Path("myresource")
public class MyResource 

    /**
     * Method handling HTTP GET requests. The returned object will be sent
     * to the client as "text/plain" media type.
     *
     * @return String that will be returned as a text/plain response.
     */
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String getIt() 
        return "Got it!";
    

    @Path( "complexObject/name" )
    @GET
    @Produces(  MediaType.APPLICATION_JSON  )
    public ComplexObject complexObject( @PathParam( "name" ) String name ) 
        return new ComplexObject(name, System.currentTimeMillis(), 42L);
    

【讨论】:

看起来您复制的是 MyResource 源代码而不是 Bean 源代码。【参考方案5】:

发现这也能正常工作,并且是解决问题的最简单方法 (AFAIT)

在你的 pom.xml 中包含以下依赖项/在 lib 路径中包含相应的 JAR 文件

<dependency>
    <groupId>com.owlike</groupId>
    <artifactId>genson</artifactId>
    <version>0.99</version>
</dependency

Link here

【讨论】:

【参考方案6】:

只需使用@XmlElement 代替@XmlAttribute(只有属性接收@ 前缀,可能重新启动您的应用服务器以更改效果!)

【讨论】:

以上是关于Jersey 2.0 相当于 POJOMappingFeature的主要内容,如果未能解决你的问题,请参考以下文章

jersey 2.0 jaxrs RI - 在异常时返回 json 字符串

使用 oAuth 2.0 保护基于 Jersey 的 REST 服务

SocketException:连接重置 - 客户端 Jersey 2.0 Java 7

JDK1.6使用jersey多少版本

Jersey POST 请求并关闭 InputStream

Jersey Rest服务类型