2015-01-20 11 views
5

Wir haben eine JAX-RS-Anwendung, die auf Apache TomEE läuft. Wir passen den Standard-Jettison-Anbieter leicht an, um die JSON-Konventionen, die von JavaScript-Frontend verwendet werden, besser einzuhalten. TomEE ermöglicht es über seine resources.xml zu tun, Datei:Anpassen von JSON marhsalling mit GlassFish v4

<resources> 
    <Service id="jettison" class-name="org.apache.cxf.jaxrs.provider.json.JSONProvider"> 
     serializeAsArray = true 
     dropRootElement = false 
     arrayKeys = members,roles 
     supportUnwrapped = true 
     writeXsiType = false 
    </Service> 
</resources> 

Jetzt sind wir auf Glassfish v4.1 migrieren, und wir feststellen, dass JSON Ausgabe unterscheidet sich von dem, was wir in TomEE hatte - also völlig Bruch Frontend. Ich suche nach einem ähnlichen Mechanismus, um JSON Marshaller in GlassFish anzupassen. In der Tat, ich bin schon ein wenig stuck mit Jersey, MOXy, Jackson, Jettison. Woher wissen wir, welcher JSON-Provider tatsächlich verwendet wird? Wie wählen wir einen aus? Wie passen wir das Verhalten an?

Die Anwendung ist reines JAX-RS und verwendet keinen JSON-Prozessor direkt, sondern beruht auf dem Marshalling JAXB-annotierter Klassen. Die Einführung von Nicht-JavaEE-Abhängigkeiten ist äußerst unerwünscht, da die Anwendung über Container (TomEE, GlassFish, einige Tage WildFly) portierbar sein soll. Config-Datei-Methode, ähnlich wie TomEE, ist vorzuziehen; Programmatic Way ist auch akzeptabel - aber nur, wenn Portabilität beibehalten wird.

Antwort

2

Glassfish verwendet MOXy als Standardanbieter. Intern hat die Bibliotheken Jackson, Jettison und MOXy zu behandeln, aber der Standard ist MOXy. Es gibt zwei Möglichkeiten moxy

  1. Set die Jersey Eigenschaft jersey.config.server.disableMoxyJson zu true zu deaktivieren.
  2. Registrieren Sie eine andere XxxJsonFeature, die MOXy deaktiviert. Zum Beispiel der JacksonFeature die

Hinweis mit jersey-media-json-jackson kommt, dass Glassfish mit einem Jackson-Provider kommt, aber es ist Jackson 1.x Wenn Sie 2.x verwenden möchten, statt die die jersey-media-json-jackson Abhängigkeit oben aufgeführten verwenden, wäre es besser, die zugrunde liegende Jackson Anbieter Abhängigkeit zu verwenden, die

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

Sie ist kann die JacksonJsonProvider oder die JacksonJaxbJsonProvider für JAXB registrieren Annotationsunterstützung.

Konfigurieren Sie Jackson, der einfachste Weg, um eine ContextResolver zu implementieren, wie in this answer zu sehen. Der JacksonJsonProvider sucht dieses ContextResolver, um das ObjectMapper abzurufen, das für (De-) Serialisierung verwandt wird.

Sie müssen auch daran denken, MOXy wie oben erwähnt zu deaktivieren.

Auch eine Sache zu beachten ist, dass diese Lösung tragbar ist. Mit JAX-RS, die einzige portable Anwendung, die Konfiguration durch eine Application Unterklasse ist

@ApplicationPath("/api") 
public class MyApplication extends Application {} 

aber sagt, dass die Sperrung von moxy im Fall von Glasfischen, ist nichts anderes als eine Eigenschaft festlegen. In der Klasse Application können Sie getProperties() überschreiben, was eine Map<String, Object> zurückgibt. Hier können Sie die Eigenschaft festlegen.Und weil es nichts anderes als ein String (keine äußeren Abhängigkeiten) s, bleibt es tragbar

@ApplicationPath("/api") 
public class MyApplication extends Application { 
    @Override 
    public Map<String, Object> getProperties() { 
     Map<String, Object> props = new HashMap<>(); 
     props.put("jersey.config.server.disableMoxyJson", true); 
     return props; 
    } 
} 

Was die oben Jackson Abhängigkeit, es ist auch eine tragbare Lösung. Es ist nichts (JAX-RS) Implementierung spezifisch. Es implementiert und verwendet Standard-JAX-RS APIs

+0

Herausfinden über 'jersey.config.server.disableMoxyJson' nahm mich wie ein Tag. Endlich habe ich meinen Gson-Provider am arbeiten. Vielen Dank! –