2015-07-24 11 views
6

Ich benutze Jersey und Jackson, um eine einfache JSON API zu erstellen.Warum ignoriert Jersey meine Jackson-Anmerkungen?

Einige der Objekte, die serialisiert werden, haben benutzerdefinierte enum-Felder. Standardmäßig werden diese Enums in eine Zeichenkette konvertiert, die auf dem Enum-Vale basiert - ich möchte die Enums zu have slightly more complex serializations.

Ich verwende Jackson Annotationen innerhalb der Enum, aber der Endpunkt scheint sie zu ignorieren. Ich habe meine Räder gedreht, um herauszufinden, wo das Problem liegt, und jetzt wende ich mich an Sie.

Enum-Code

package org.example.code; 

import com.fasterxml.jackson.annotation.JsonFormat; 
import com.fasterxml.jackson.annotation.JsonProperty; 

@JsonFormat(shape= JsonFormat.Shape.OBJECT) 
public enum ExampleEnum { 
    YES (1, "Yes indeed"), 
    NO (2, "No way buddy") 

    private final Integer code; 
    private final String description; 

    ExampleEnum(final Integer code, final String description) { 
     this.code = code; 
     this.description = description; 
    } 

    @JsonProperty("code") 
    public Integer getCode() { 
     return code; 
    } 
    @JsonProperty("description") 
    public String getDescription() { 
     return description; 
    } 
} 

API-Code

package org.example.webservice.impl; 

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

import org.example.code.ExampleEnum; 


@Path("/example") 
public class ExampleService { 
    @GET 
    @Path("/test") 
    @Produces({MediaType.APPLICATION_JSON}) 
    public ExampleEnum getExampleEnum() { 
     return ExampleEnum.YES; 
    } 
} 

Wenn ich den Endpunkt nennen example/test die Ausgabe YES Was ich will, ist die Ausgabe etwas entlang der Linien zu sein, { code: 1, description: "Yes indeed" }

unter

Konfigurationsdateien sind ...

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <groupId>org.example</groupId> 
    <artifactId>api</artifactId> 
    <version>0.0.1</version> 
    <packaging>war</packaging> 

    <name>example API</name> 
    <url>http://example.org</url> 

    <properties> 
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
    </properties> 

    <dependencies> 

     <dependency> 
      <groupId>javax.ws.rs</groupId> 
      <artifactId>javax.ws.rs-api</artifactId> 
      <version>2.0.1</version> 
     </dependency> 

     <dependency> 
      <groupId>javax.annotation</groupId> 
      <artifactId>javax.annotation-api</artifactId> 
      <version>1.2</version> 
     </dependency> 

     <dependency> 
      <groupId>com.fasterxml.jackson.core</groupId> 
      <artifactId>jackson-databind</artifactId> 
      <version>2.6.0</version> 
     </dependency> 

     <dependency> 
      <groupId>org.glassfish.jersey.containers</groupId> 
      <artifactId>jersey-container-servlet-core</artifactId> 
      <version>2.18</version> 
     </dependency> 
    </dependencies> 

    <build> 
     <plugins> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-compiler-plugin</artifactId> 
       <version>3.3</version> 
       <configuration> 
        <source>1.7</source> 
        <target>1.7</target> 
       </configuration> 
      </plugin> 
      <plugin> 
       <groupId>org.apache.tomcat.maven</groupId> 
       <artifactId>tomcat7-maven-plugin</artifactId> 
       <version>2.2</version> 
       <configuration> 
        <url>http://localhost:8080/manager/text</url> 
        <server>TomcatServer</server> 
        <path>/example</path> 
       </configuration> 
      </plugin> 
     </plugins> 
    </build> 

</project> 

web.xml

<?xml version="1.0" encoding="UTF-8"?> 
<web-app version="3.0" 
    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_3_0.xsd"> 
    <display-name></display-name> 
    <servlet> 
    <display-name>Example Servlet</display-name> 
    <servlet-name>Example Servlet</servlet-name> 
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> 
    <init-param> 
     <param-name>jersey.config.server.provider.packages</param-name> 
     <param-value>org.example.webservice.impl</param-value> 
    </init-param> 
    <init-param> 
     <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name> 
     <param-value>true</param-value> 
    </init-param> 
    <init-param> 
     <param-name>jersey.config.server.provider.classnames</param-name> 
     <param-value>org.glassfish.jersey.filter.LoggingFilter;org.glassfish.jersey.media.multipart.MultiPartFeature</param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
    </servlet> 
    <servlet-mapping> 
    <servlet-name>Example Servlet</servlet-name> 
    <url-pattern>/services/*</url-pattern> 
    </servlet-mapping> 
    <welcome-file-list> 
    <welcome-file>index.jsp</welcome-file> 
    </welcome-file-list> 
</web-app> 
+0

Aus Neugier, wie funktioniert Ihre App überhaupt? Ich frage, weil ich das Tomcat-Plugin sehe, aber ich sehe nur die JAX-RS API-Abhängigkeit, kein Jersey. Führst du Glassfish zufällig? Bitte klären Sie. –

+0

Sie sind richtig, Herr/Madame! Ich habe versucht, einige der irrelevanten Gläser auszuziehen, bevor ich die Frage gestellt habe, und fälschlicherweise auch Glasfische fallen gelassen. Hinzugefügt. – slifty

Antwort

4

So ein paar Dinge:

  • com.sun.jersey.api.json.POJOMappingFeature ist für Jersey 1.x, also können Sie das loswerden.

  • MOXy ist der Standardanbieter in Glassfish. Wenn Sie also Jackson verwenden möchten, müssen Sie MOXy deaktivieren. Sie können durch das Hinzufügen dieser <init-param>

    <init-param> 
        <param-name>jersey.config.server.disableMoxyJson</param-name> 
        <param-value>true</param-value> 
    </init-param> 
    
  • Dann so tun als @Alexey Gavrilov wies darauf hin, fügen Sie den Jackson-Anbieter

    <dependency> 
        <groupId>com.fasterxml.jackson.jaxrs</groupId> 
        <artifactId>jackson-jaxrs-json-provider</artifactId> 
        <version>2.6.0</version> 
    </dependency> 
    
  • Sie diesen Anbieter durch Hinzufügen des Pakets an den Paketen registrieren zu scannen

    <init-param> 
        <param-name>jersey.config.server.provider.packages</param-name> 
        <param-value> 
         org.example.webservice.impl, 
         com.fasterxml.jackson.jaxrs.json 
        </param-value> 
    </init-param> 
    

andere Sache, die nichts zu tun hat Zu diesem Thema, auf das ich hinweisen möchte, ist, dass Glassfish bereits eine Jersey-Implementierung hat, die eine sehr alte 2.x-Version ist, vielleicht 2.0. Wenn Sie Runtime-Jersey-Abhängigkeiten hinzufügen, können Konflikte auftreten. Ich würde eines von zwei Dingen tun, entweder alle Jersey Abhängigkeiten in eine provided<scope> oder wenn Sie Anforderungen für die spätere Version Funktionalität haben, möchten Sie vielleicht in Update der Jersey-Version in Glassfish zu überprüfen. Werfen Sie einen Blick auf Updating Jersey 2 in GlassFish 4

+0

"DisableMoxyJson", so wichtig zu wissen! Danke! +1 – Sebastian

0

Glassfish hat jackson jar in sich und es kann Konflikte mit expliziten jackson jars haben, die Sie in pom.xml deklariert haben.

In der Maven-Website gibt es für jede Version des JARS nur wenige weitere JARs zum Kompilieren von Abhängigkeiten in dem von Ihnen ausgewählten JAR.

So konnten die auch mit den Gläsern in Konflikt, die Sie in pom.xml erklärt haben

enter image description here

Ich entfernte auch

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

von pom.xml

0

Für Jersey 2.2x Benutzer, die die Application-Klasse anstelle von web.xml verwenden, das funktioniert für mich

1. In ResourceConfig,

@ApplicationPath("rest") 
public class JerseyApplication extends ResourceConfig { 
    public JerseyApplication() { 
     packages("com.example.rest"); 
     register(JacksonFeature.class);      
    } 
} 

Oder, wenn Sie Application-Klasse verwenden,

public class MyApplication extends Application { 

    public Set<Class<?>> getClasses() { 
     final Set<Class<?>> classes = new HashSet<Class<?>>(); 
     . 
     . 
     classes.add(JacksonFeature.class); 
     return classes; 
    } 
} 

2. In pom.xml, fügen Sie diese Abhängigkeit,

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

3. Vergewissern Sie sich, dass Sie einen Kommentar haben Ionen auf Getter und Setter. In meinem Fall funktionierte @JsonIgnore Annotation nur, wenn ich es auf Getter und Setter dieser Klassenvariablen verwendete.

Verwandte Themen