Use Jackson as JAXB-JSON-processor in JavaEE Appli

2019-02-25 03:15发布

I've seen many articles and SO-questions about this - but I just don't get it working. My goal is to use Jackson as JSON processor in a JavaEE application. What do I have so far?

pom.xml

  • either this one

    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
        <version>2.17</version>
    </dependency>
    
  • or this one (which of them is correct in the end?)

    <dependency>
        <groupId>com.fasterxml.jackson.jaxrs</groupId>
        <artifactId>jackson-jaxrs-json-provider</artifactId>
        <version>2.5.2</version>
    </dependency>
    
  • plus this (due to this article, because auto discovery shall not exist in jackson packages anymore):

    <dependency>
        <groupId>org.glassfish.jersey.ext</groupId>
        <artifactId>jersey-metainf-services</artifactId>
        <version>2.17</version>
    </dependency>
    

web.xml

Simple REST registration:

<servlet>
    <servlet-name>javax.ws.rs.core.Application</servlet-name>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>javax.ws.rs.core.Application</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

A simple Object

import com.fasterxml.jackson.annotation.JsonProperty;

public class Dummy {
    private String name;

    @JsonProperty("username")
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

The REST resource

@GET
@Path("test")
@Produces(MediaType.APPLICATION_JSON)
public Response getRequest() {
    Dummy dummy = new Dummy();
    dummy.setName("rolf");

    return Response.ok(dummy).build();
}

And the output is

{"name":"rolf"}

instead of the expected

{"username":"rolf"}

Update

I'm using the GlassFish application server.

1条回答
疯言疯语
2楼-- · 2019-02-25 03:59

My guess would be you're on Glassfish, which uses MOXy as its default JSON provider. You can disable it with an <init-param>.

<init-param>
    <param-name>jersey.config.server.disableMoxyJson</param-name>
    <param-value>true</param-value>
</init-param>

The jersey-media-json-jackson has an auto-discoverable feature that should automatically register it. I'm not sure about the auto-discoverable feature in the case of Glassfish, and possible lower version of Jersey it uses internally, and if it will cause it not to be register. But either way, the way you have configured you web.xml is to enable classpath scanning, so the Jackson provider should be picked up anyway.

Some FYIs

  • jersey-media-json-jackson actually uses jackson-jaxrs-json-provider. It just wraps it in a JacksonFeature, and enables auto-discovery of it.
  • If it still doesn't work, you can try to create a feature to handle the registering and disabling. For example

    @Provider
    public class JsonFeature implements Feature {
        @Override
        public boolean configure(FeatureContext context) {
            context.property("jersey.config.server.disableMoxyJson", true);
            // this is in jersey-media-json-jackson
            context.register(JacksonFeature.class);
    
            // or from jackson-jaxrs-json-provider
            context.register(JacksonJsonProvider.class);
            // for JAXB annotation support
            context.register(JacksonJaxbJsonProvider.class);
    
            return true;
        }
    }
    
查看更多
登录 后发表回答