Frage

Ich verwende Spring MVC JSON POST-Anfragen zu behandeln. Unter den Abdeckungen verwende ich die MappingJacksonHttpMessageConverter auf dem Prozessor Jackson JSON gebaut und aktiviert, wenn Sie die Mvc verwenden: Annotation-driven

.

Einer meiner Dienste erhält eine Liste von Aktionen:

@RequestMapping(value="/executeActions", method=RequestMethod.POST)
    public @ResponseBody String executeActions(@RequestBody List<ActionImpl> actions) {
        logger.info("executeActions");
        return "ACK";
    }

Ich habe festgestellt, dass Jackson bildet die requestBody auf eine Liste der java.util.LinkedHashMap Artikel (einfache Datenbindung). Stattdessen würde ich die Anfrage gerne eine Liste der typisierte Objekte gebunden zu sein (in diesem Fall „ActionImpl“).

Ich weiß, das ist einfach zu tun, wenn Sie Jackson ObjectMapper direkt verwenden:

List<ActionImpl> result = mapper.readValue(src, new TypeReference<List<ActionImpl>>() { }); 

aber ich frage mich, was der beste Weg, dies zu erreichen, wenn Spring MVC und MappingJacksonHttpMessageConverter verwenden. Irgendwelche Hinweise?

Danke

War es hilfreich?

Lösung

Ich vermute Problem wird durch Löschen von Daten geben, das heißt, statt generische Parameter Typen vorbei, vielleicht nur actions.getClass () übergeben wird; und dies würde Typen äquivalent Liste geben .

Wenn das wahr ist, eine Möglichkeit, eine Zwischenunterklasse zu verwenden wäre, wie:

public class ActionImplList extends ArrayList<ActionImpl> { }

da dies die Typinformation behalten, auch wenn nur die Klasse übergeben wird. Also dann:

public @ResponseBody String executeActions(@RequestBody ActionImplList actions)

würde den Trick tun. Nicht optimal, aber sollte funktionieren.

Ich hoffe, dass jemand mit mehr Spring MVC Wissen beleuchten kann, warum ist Parametertyp nicht übergeben wird (vielleicht ist es ein Bug?), Aber zumindest gibt es eine Arbeit um.

Andere Tipps

Ich habe festgestellt, dass Sie auch unter Verwendung eines Array als @RequestBody anstelle einer Sammlung, die Art Lösch Problem umgehen können. Zum Beispiel würde folgende Arbeiten:

public @ResponseBody String executeActions(@RequestBody ActionImpl[] actions) { //... }

Für Ihre Informationen wird die Funktion verfügbar sein https://jira.springsource.org/browse / SPR-9570 )

Ich habe es getestet nur auf aktuelle M2 und es wirkt wie ein Zauber aus der Box (keine Notwendigkeit, zusaetzliche Anmerkung, um die parametrisierte Art zu schaffen, wird es automatisch durch neue MessageConverter aufgelöst werden)

Diese Frage ist schon alt, aber ich denke, ich sowieso ein wenig beitragen kann.

Wie StaxMan wies darauf hin, dies aufgrund ist Löschung einzugeben. Es definitiv sollte möglich sein, weil Sie können die allgemeinen Argumente über Reflexion von der Methodendefinition erhalten. Doch das Problem ist die API der HttpMessageConverter :

T read(Class<? extends T> clazz, HttpInputMessage inputMessage);

Hier wird nur List.class wird an die Methode übergeben werden. So, wie Sie sehen können, ist es unmöglich zu implementieren einer HttpMessageConverter dass berechnet die realen Art von auf dem Methodenparameter Typen suchen, wie die nicht verfügbar ist.

Dennoch ist es möglich, eigene Problemumgehung Code - Sie einfach nicht HttpMessageConverter werden. Spring MVC können Sie Ihre eigenen WebArgumentResolver dass Tritte in vor der Standardauflösung Methoden. Sie können Ihre eigene benutzerdefinierte Anmerkung (@JsonRequestBody?) Beispielsweise verwenden, die direkt einen ObjectMapper verwendet Ihren Wert zu analysieren. Sie werden den Parametertyp aus dem Verfahren liefern können:

final Type parameterType= method.getParameterTypes()[index];
List<ActionImpl> result = mapper.readValue(src, new TypeReference<Object>>() {
    @Override
    public Type getType() {
        return parameterType;
    }
});

Nicht wirklich die Art und Weise TypeReference sollte verwendet werden, nehme ich an, aber ObjectMapper bietet keine geeignetere Methode.

Haben Sie die Methode, wie versucht zu erklären:

executeActions(@RequestBody TypeReference<List<ActionImpl>> actions)

Ich habe es nicht ausprobiert, aber auf der Grundlage Ihrer Frage, es ist das erste, was ich würde versuchen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top