获取JAX-RS服务以使用JsonObject属性创建对象

时间:2015-10-31 19:21:12

标签: java json glassfish jersey jax-rs

我想让JAXRS将特定类属性的所有json细节都推送到JsonObject对象中。

假设我有以下课程:

public class MyMessage implements Serializable {

    private PayloadType payloadType;    

    private JsonObject payload;
}

REST方法:

@POST
@Path("/send")
@Consumes(MediaType.APPLICATION_JSON)
public Response send(MyMessage message) 

我想发布以下JSON,但将payload属性设置为javax.json.JsonObject对象。

{
   payloadType:'MESSAGE',
   payload:{
      subject:"My Subject",
      body:"This is a message"
   }
}

我在Glassfish上运行,所以我期待JsonObject包含org.glassfish.jersey.media的消息阅读器,这是支持包含在GF4.1中。添加以下maven依赖项只会导致不明确的类异常。

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-processing</artifactId>
    <version>2.22.1</version>
</dependency>

1 个答案:

答案 0 :(得分:0)

So there are a couple things stopping you here.

  1. javax.json (or JSONP) does not handle POJOs. It only handles the javax.json API. If you what you are expecting is that the original provider handle the POJO, while the JSONP provider handle the javax.json, it doesn't work like that. Either you will use the one that handles the POJOs (which doesn't know javax.json or you use the one that handles javax.json. (We do make this happen below though :-)

  2. Glassfish's default provider is MOXy. So we need to disable to to use any other provider. To disable MOXy, you need to set this property

    ServerProperties.MOXY_JSON_FEATURE_DISABLE

    true。在您的web.xml或Java配置中。

  3. 为了使这项工作,我们应该确保我们使用杰克逊。杰克逊拥有jackson-datatype-jsr353模块,可以在POJO中完成你想要做的事情,javax.json

    Glassfish已经拥有Jackson提供商,但您应该在provided范围内添加它。所以添加这两个依赖项

    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
        <version>2.10.4</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr353</artifactId>
        <version>2.3.3</version>
    </dependency>
    

    如果你注意版本,我使用的是Glassfish 4.1中包含的相同版本。它使用Jersey 2.10.4和Jackson 2.3.3。您希望版本冲突。即使提供了jersey-media-json-jackson,在编译时尝试使用与服务器相同的版本仍然是一个好主意。

    此外,您应该在申请时注册JacksonFeature

    我们最不需要的是注册JSR353Module,以便我们可以获得杰克逊的javax.json支持。要做到这一点,只需在您的应用程序中注册以下提供程序。

    @Provider
    public class ObjectMapperProvider implements ContextResolver<ObjectMapper> {
    
        private final ObjectMapper mapper;
    
        public ObjectMapperProvider() {
            mapper = new ObjectMapper();
            mapper.registerModule(new JSR353Module());
        }
    
        @Override
        public ObjectMapper getContext(Class<?> type) {
            return mapper;
        }
    }
    

    那就是它。我已经测试了它,它应该可以工作。