2015-07-24 26 views
6

Sto utilizzando Jersey e Jackson per creare una semplice API JSON.Perché Jersey ignora le mie annotazioni su Jackson?

Alcuni degli oggetti serializzati dispongono di campi enum personalizzati. Per impostazione predefinita, queste enumerazioni vengono convertite in una stringa basata sull'enum vale: mi piacerebbe l'enumerazione su have slightly more complex serializations.

Sto usando le annotazioni di Jackson all'interno dell'enumerazione, ma l'endpoint sembra ignorarle. Sto girando le ruote cercando di capire dove si trova il problema, e ora mi rivolgo a te.

Enum Codice

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; 
    } 
} 

Codice API

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; 
    } 
} 

Quando chiamo il punto finale example/test l'uscita è YES Quello che voglio è l'uscita di essere qualcosa sulla falsariga di { code: 1, description: "Yes indeed" }

I file di configurazione sono al di sotto ...

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

Per curiosità, come funziona la tua app? Sto chiedendo perché vedo il plugin per il tomcat, ma vedo solo la dipendenza da API JAX-RS, niente Jersey. Stai usando Glassfish per caso? Si prega di precisare. –

+0

Sei corretto signore/signora! Ho provato a spogliare alcuni dei vasetti irrilevanti prima di postare la domanda e, per errore, ho lasciato cadere anche il glassfish. Aggiunto. – slifty

risposta

4

Così un paio di cose:

  • com.sun.jersey.api.json.POJOMappingFeature è per Jersey 1.x, quindi puoi sbarazzartene.

  • MOXy è il provider predefinito in Glassfish, quindi se si desidera utilizzare Jackson, è necessario disabilitare MOXy. Puoi farlo aggiungendo questo <init-param>

    <init-param> 
        <param-name>jersey.config.server.disableMoxyJson</param-name> 
        <param-value>true</param-value> 
    </init-param> 
    
  • Poi, come @Alexey Gavrilov ha sottolineato, aggiungere il provider Jackson

    <dependency> 
        <groupId>com.fasterxml.jackson.jaxrs</groupId> 
        <artifactId>jackson-jaxrs-json-provider</artifactId> 
        <version>2.6.0</version> 
    </dependency> 
    
  • È possibile registrare questo fornitore aggiungendo il pacchetto per i pacchetti per la scansione

    <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> 
    

Un'altra cosa che non è correlato a questo problema che potrei sottolineare, Glassfish ha già un'implementazione di Jersey, che è una versione 2.x molto vecchia, forse 2.0. Quando si aggiungono le dipendenze del runtime Jersey, potrebbero entrare in conflitto. Vorrei fare una delle due cose, o mettere tutte le dipendenze di Jersey in un provided<scope> o se hai i requisiti per la funzionalità della versione successiva, potresti voler controllare l'aggiornamento della versione di Jersey in Glassfish. Date un'occhiata a Updating Jersey 2 in GlassFish 4

+0

"disableMoxyJson", così importante da sapere! grazie! +1 – Sebastian

0

Glassfish ha un barattolo di Jackson in sé e potrebbe avere dei conflitti con i jacks di jackson espliciti che avete dichiarato in pom.xml.

Nel sito Web di Maven, per ogni versione del contenitore, ci sono pochi altri barattoli di dipendenze nel tempo di compilazione all'interno del barattolo scelto.

Così quelli potrebbe anche essere in conflitto con i vasi che si sono pronunciati a pom.xml

enter image description here

Ho anche tolto

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

da pom.xml

0

Per Jersey 2.2x utenti che usano la classe Application invece di usare web.xml, questo funziona per me

1. In ResourceConfig,

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

Oppure, se si utilizza classe Application,

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, aggiungere questa dipendenza,

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

3. Assicurarsi di avere annotat ioni su getter e setter. Nel mio caso l'annotazione @JsonIgnore ha funzionato solo quando l'ho usata su getter e setter di quella variabile di classe.