我想创建一个按条件将值写入@RequestBody的拦截器。但是,如何在spring调用@PostMapping之前立即进行拦截?

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

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


然后,我发送POST正文:

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


要发送网址:localhost:8080?_someparam=val

我的目标是检测是否存在任何查询参数,然后直接写入从Person主体生成的POST对象。

我知道我可以在servlet方法中轻松实现这一目标。但是,这只是一个示例,我想将此逻辑全局应用于所有请求。因此,由于不必在每个POST请求上重复相同的代码调用,我想使用某种拦截器直接将其写入生成的对象(反射会很好)。

但是:有可能吗? Spring在@PostMapping之前执行什么方法?也许有人可以挂在那里?

最佳答案

在春季,messageConverters负责将json字符串反序列化为对象。在您的情况下,这应该是MappingJackson2HttpMessageConverter。

您可以使用自己的实现覆盖它,并覆盖如下的read方法:

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


您可以通过实现自己的WebMvcConfigurer并覆盖configureMessageConverters方法来注册自己的自定义messageConverter。

在这里无法尝试,但是应该可以!

07-27 18:35