membersound
membersound

Reputation: 86875

How to access @RequestBody before @PostMapping is called?

I want to create an interceptor that writes a value to the @RequestBody by condition. But how can I intercept right before the @PostMapping is called by spring?

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

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

Then I send the POST body:

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

To url: localhost:8080?_someparam=val

My goal is to detect if any query param is present, and then directly write to the Person object that has been generated from the POST body.

I know I could achieve this easily within the servlet method. BUT as this is just an example, I want to apply this logic globally to all requests. Thus, for not having to repeat the same code call on every POST request, I'd like to have some kind of interceptor to write directly to the generated object (reflection would be fine).

But: is that possible? What method is executed by spring right before the @PostMapping? Maybe one could hook up there?

Upvotes: 2

Views: 1998

Answers (1)

tvvk
tvvk

Reputation: 99

in spring the messageConverters are responsible for (de-)serializing json strings into objects. In your case this should be the MappingJackson2HttpMessageConverter.

You could overwrite it with your own implementation and overwrite the read method like this:

@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...
  }
}

You can register than your own custom messageConverter by implementing your own WebMvcConfigurer and overwrite the configureMessageConverters method.

Couldn't try it here, but this should work!

Upvotes: 1

Related Questions