2017-11-08 16 views
2

Ich möchte einen Interceptor erstellen, der einen Wert an die @RequestBody durch Bedingung schreibt. Aber wie kann ich abfangen, bevor die @PostMapping vom Frühjahr aufgerufen wird?Wie kann @RequestBody aufgerufen werden, bevor @PostMapping aufgerufen wird?

@RestController 
public class PersonServlet { 
    @PostMapping("/person") 
    public void createPerson(@RequestBody Person p) { 
     //business logic 
    } 

    class Person { 
     String firstname, lastname; 
     boolean getQueryParamPresent = false; 
    } 
} 

Dann schicke ich die POST Körper:

{ 
    "firstname": "John", 
    "lastname": "Doe" 
} 

Um url: localhost:8080?_someparam=val

Mein Ziel ist es zu erkennen, wenn eine Abfrage param vorhanden ist, und dann schreiben Sie direkt an das Person Objekt, das wurde aus dem POST Körper generiert.

Ich weiß, ich könnte dies leicht innerhalb der Servlet-Methode erreichen. ABER da dies nur ein Beispiel ist, möchte ich diese Logik global auf alle Anfragen anwenden. Um also nicht den gleichen Code-Aufruf bei jeder Anfrage zu wiederholen, hätte ich gerne eine Art Interceptor, um direkt auf das generierte Objekt zu schreiben (Reflektion wäre in Ordnung).

Aber: ist das möglich? Welche Methode wird im Frühjahr vor der @PostMapping ausgeführt? Vielleicht könnte man dort einhaken?

+0

Scheint wie ein guter Platz für einen MVC HandlerInterceptor. –

+0

Können Sie ein Beispiel geben? – membersound

+0

Dieser Artikel bietet ein gutes Beispiel. Aber Sie müssen möglicherweise einige manuelle JSON-Manipulation durchführen. https://examples.javacodegeeks.com/enterprise-java/spring/mvc/spring-mvc-interceptor-tutorial/ –

Antwort

1

im Frühjahr sind die messageConverters dafür verantwortlich, json strings in Objekte zu de- bzw. serialisieren. In Ihrem Fall sollte dies der MappingJackson2HttpMessageConverter sein.

Man könnte es mit Ihrer eigenen Implementierung überschreiben und die Lese Methode wie folgt überschrieben:

@Service 
public class MyMessageConverter extends MappingJackson2HttpMessageConverter 

@Autowired Provider<HttpServletRequest> request; 

@Override 
public Object read(Type type, @Nullable Class<?> contextClass, HttpInputMessage inputMessage) 
     throws IOException, HttpMessageNotReadableException { 
    Object result = super.read(type, contextClass, inputMessage); 
    if (result instanceof Person) { 
    HttpServletRequest req = request.get(); 
    // Do custom stuff with the request variables here... 
    } 
} 

Sie Ihre eigenen messageConverter registrieren kann, als durch eigene WebMvcConfigurer Implementierung und die configureMessageConverters Methode überschreiben.

Konnte es hier nicht versuchen, aber das sollte funktionieren!

+0

Ok, ich kann nicht den Konverter selbst haken es scheint. – membersound

+0

Nun, dies ist eine Option, dies zu tun - ein anderes wäre, einen benutzerdefinierten Deserializer wie hier beschrieben zu registrieren: http://www.baeldung.com/jackson-deserialization ... aber diese werden nicht von Frühjahr verwaltet, also Sie würde einen anderen Trick benötigen, um Ihre Anfrageparameter zu erhalten. – tvvk

Verwandte Themen