Benutzerdefinierte HttpMessageConverter in Spring MVC
Bei der Implementierung von RESTful API ich wickle alle meine Daten in ein Objekt, so sieht es so aus.
{error: null, code: 200, data: {...actual data...}}
Diese Ergebnisse bei sich wiederholenden code, den ich überall verwenden zu wickeln Daten:
@Transactional
@RequestMapping(value = "/", method = RequestMethod.GET)
public @ResponseBody Result<List<BookShortDTO>> books() {
List<Book> books = booksDao.readBooks();
return Result.ok(books); //this gets repeated everywhere
}
Die Frage ist also, wie ändere ich diese (vielleicht mit Verwendung von benutzerdefinierten HttpMessageConverter vielleicht noch andere Möglichkeiten?) gerade zurück booksDao.readBooks() und, um es gewickelt automatisch.
- Hinzufügen jackson 2+, um den Klassenpfad für die zu serialisieren und Deserialisieren von JSON mit
MappingJackson2HttpMessageConverter
. - Es ist bereits da. Die Frage ist, dass ich will, es zu wrap-mein Ergebnis in der Ergebnis-Objekt automatisch, so dass ich nicht zum schreiben zurück Führen.ok(Bücher); in jeder Antwort
- Durch
Result.ok
, sollten wir davon ausgehen, dass Sie andereResult
Methoden für die verschiedenen Fehlercodes und Nachrichten? - Gut, ja. Zum Beispiel kann ich das Ergebnis zurückgeben.verboten (ist), wenn der Benutzer nicht über entsprechende Rechte
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wie @Ralph vorgeschlagen, die Sie verwenden können, eine
HandlerMethodReturnValueHandler
zu wickeln Sie Ihre Handler-Wert zurückgeben.Der einfachste Weg dies zu erreichen ist durch die Erweiterung
RequestResponseBodyMethodProcessor
und verändern, es ist Verhalten ein bisschen. Am besten erstellen Sie eine benutzerdefinierte Beschriftung zu markieren Sie Ihre handler-Methoden mit. Dies wird sicherstellen, dass IhrHandlerMethodReturnValueHandler
aufgerufen werden, anstatt von anderen, dieRequestMappingHandlerAdapter
standardmäßig.Hier ist eine einfache Implementierung des benutzerdefinierten
HandlerMethodReturnValueHandler
namensResultResponseHandlerMethodProcessor
die Unterstützung Rückgabewerte von Methoden, annotiert mitResultResponseBody
. Es ist ziemlich einfach. Nur das überschreiben dersupportsReturnType()
undhandleReturnValue()
Methoden entsprechend Ihren Anforderungen (wickeln Sie den Rückgabewert in eineResult
- Typ).Das einzige, was Links ist, fügen Sie diese Klasse, um die Liste der benutzerdefinierten
HandlerMethodReturnValueHandler
s und bieten es mit einemMappingJackson2HttpMessageConverter
Instanz.supportsReturnType
so lange es nicht die gleiche wie die super-Klasse - oder habe ich etwas verpasst?supportsReturnType
ist das gleiche wieRequestResponseBodyMethodProcessor
dannRequestResponseBodyMethodProcessor
wird das zu handhaben ist der Rückgabewert. Nicht die benutzerdefinierte handler.Denke ich, eher als eine änderung der message-Wandler (was funktionieren würde), würde ich eine AOP-Ansatz - um-Beratung in allen die entsprechenden controller-Methoden wäre Recht einfach einzurichten. Es würde Ihnen auch einen schöneren Programmier-Modell, und feinere Kontrolle über die Methoden abgefangen werden.
RequestMappingHandlerAdapter
bietet eine Liste vonHandlerMethodReturnValueHandler
s, so dass Sie nicht haben, um resort-AOP. Ich würde AOP nur, wenn es die Letzte mögliche Lösung.Könnte man eine
HandlerMethodReturnValueHandler
zu ersetzen, das Ergebnis.Der entscheidende Punkt ist: ersetzen Sie die return-Wert vor der übertragung der (modifizierten) retunr Wert auf das serialisieren.
Finden Sie in diesem blog: http://martypitt.wordpress.com/2012/11/05/custom-json-views-with-spring-mvc-and-jackson/ für ein Beispiel, wie so archivieren Sie eine ähnliche (nicht die gleichen) Ziel. Es auch beschreiben, eine Methode für die Registrierung der
HandlerMethodReturnValueHandler
(für einen anderen sehen Barts Antwort)Möchte ich versuchen, und Sie davon überzeugen, dass das, was Sie tun, ist richtig und erfordert keine änderungen.
Als du gepostet hast in den Kommentaren zu Ihrer Frage, Sie haben eine Reihe von verschiedenen
Result
Methoden, die die Fehlermeldung, der code und die Daten. So etwas wieIch gehe davon aus, dass diese Methoden sind gedacht, um anzeigen zu den verschiedenen HTTP-status-codes, aber mit benutzerdefinierten Fehlermeldungen.
Ihre
@Controller
handler-Methoden sind gedacht, um zu behandeln eine Anfrage und bereiten eine Antwort. Das ist, was Ihre Methode ist derzeit dabei und es ist sehr explizit über was Sie tut,. Der Logik über das, was dieResult
werden sollten, gehört zu der hf-Methode, nicht eineHandlerMethodReturnValueHandler
, wie andere vorschlagen.Ich würde auch vorschlagen, mit
ResponseEntity
statt@ResponseBody
. Kehren Sie einResponseEntity
und setzen Sie den HTTP-Antwort-Header und der status-code explizit. Sie würde auch die Antwort Körper.Etwas wie
In diesem Fall werden die Standard-status-code 200.
Aber wenn Sie wollte
verwenden Sie
Frühjahr wird die gleiche
HttpMessageConverter
konvertieren Sie IhreResult
in JSON, aber hier haben Sie mehr Kontrolle über den HTTP-Antwort.Ich denke, es ist notwendig, um
ansonsten wird der default-RequestResponseBodyMethodProcessor übernehmen die Kontrolle von handling return Wert.