Spring REST mit beiden JSON und XML
Ich will eine umfassende REST-API mit Unterstützung für beide JSON
und XML
.
Dem domain-Modell ist ein komplexer Typ und wir beachten Sie, dass zu produzieren, freundliche JSON
und XML
auf dem gleichen Modell mit MappingJacksonHttpMessageConverter
und JaxbMarshaller
bzw. neigt zu geben entweder lesbaren XML-oder lesbaren JSON 1).
Was ist der beste Weg zu gehen?
1) Durch, wie die Objekte wie Karten, root-tags und Beziehungen modelliert sind unterschiedlich in json
als in xml
, die Objekte zu serialisieren, muss anders gestaltet, um sowohl sauber json
und ordentlich xml
. Dienstprogramme wie jaxb-Annotationen geht nur so weit.
Ich denken kann, ein paar Kandidaten
1) Erstellen Sie eine json-und xml-controller/model
public class Controller {
public Foo foo() {
return new Foo();
}
}
public class XmlController extends Controller {
@Override
public XmlFoo foo() {
return new new XmlFoo(super.foo());
}
}
public class JsonController extends Controller {
@Override
public JsonFoo foo() {
return new JsonFoo(super.foo());
}
}
Gegeben ein Modell-Objekt Foo
erstellen Sie eine JsonFoo
und XmlFoo
2) Schreiben Sie eine benutzerdefinierte Nachricht-Konverter
Ich versuchte dies und es stellte sich heraus, um ein bisschen kompliziert, da die anzeigen müssen wissen, wie zu lösen, z.B. ein Foo
zu einem JsonFoo
in der Lage sein, um es zu serialisieren in ein lesbares format.
3) Lassen Sie jedes Modell-Objekt serialisieren, die sich, z.B.,
public class Foo {
public String serialize(Serializer s) {
return s.serialize(this);
}
}
Basierend auf einigen Schieds-parameter lassen den controller injizieren Sie die korrekte serializer
new Foo(new FooJsonSerializer());
new Foo(new FooXmlSerializer());
- Kannst du erklären, was du damit meinst, die verschiedene designs?
- JAXB kann zum Beispiel verwendet werden, um anzeigen von/auf XML-und JSON mit den gleichen annotierten Klasse. Keine Notwendigkeit für verschiedene design.
- es ist weit davon entfernt trivial zu constuct eine aufwendige java-Struktur zu serialisieren, um beide ziemlich json und ziemlich xml.
- Ah, habe ich nicht bekommen, aus Ihrer Frage, dass Sie gefragt wurden nested - /hierarchischen Datenstrukturen. Es scheint mir, dass, wenn Sie traf den Punkt, wo Sie brauchen, um zu koordinieren, die Gestaltung der Serialisierung und der POJO, die Sie getroffen habe, der Punkt, wo eine benutzerdefinierte serializer für das Objekt sinnvoll.
- Warum ist jeder mit view-Resolver? Sie sind bestimmt für Menschen. Nachricht-Wandler sind genau für M2M-Kommunikation.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich Tue dies in einem aktuellen Projekt ohne Verwendung einer
ContentNegotiatingViewResolver
. Für eine Methode in meinem controller:Kann ich erhalten die folgende Ausgabe auf der Grundlage der
Accept
- request-header.Accept: application/xml (erfordert JAXB2 auf dem classpath)
Accept: application/json (setzt Jackson auf dem classpath)
Meine Antwort-Objekt ist einfach und nutzt die normalen Anmerkungen:
Den SpringSource spring-mvc-showcase-Projekt ist auch eine hilfreiche Ressource. Ich denke, Sie trennen die Umbauten für die verschiedenen Methoden, aber ich bin auf jeden Fall tun dies für eine Methode.
Kann ich nicht ganz sagen, durch deine Frage...aber wenn Sie schauen, um zu serialisieren, die die Ausgabe mehr als das, @chrylis ist richtig, dass eine benutzerdefinierte Serialisierung für Ihr Nächstes bewegen. Aber alles, was ich lief in (die können ziemlich Komplex, mit verschachtelten Objekten in meiner Antwort) wandelt perfekt, um gültigen XML-oder JSON.
Sollten Sie die ContentNegotiatingViewResolver.
Gibt es ein Problem, dass eine collection von POJOs sind nicht richtig zugeordnet mit einigen XML-marshallers. XStream hat Lösungen für diese (Moxy auch?).
Hier ist ein Ort, um zu starten:
http://blog.springsource.org/2013/06/03/content-negotiation-using-views/
Im Grunde, verwenden Sie eine MappingJacksonView und ein ähnliches für XML, das ist eine "fake" - anzeigen, die verwendet Jackson (oder ein XML-marshaller) nach marshall Ihre POJO(s) das richtige format.
Sendet der server zurück, über die richtige Art basiert auf einem von:
Soweit das weglassen von Feldern Dosen mit Anmerkungen @JsonIgnore(für Jackson) und/oder @XStreamOmitField(für XStream).
Hast du das probiert: