SpringMVC拦截器踩坑日记

Image by Elena Rogulina from Pixabay

前言

情景回顾:
最近和第三方一起调试接口,对方总是说调用我们的接口报重复提交的问题; 而我们关于重复提交的这个是一个统一的基础组件;所以事先排除了这个基础组件的问题; 最后经过排查,发现这个组件是从request的Parameter中获取的数据用来判断是否二次提交的,而这种方式是取不到json格式的数据的; 然而我们对外提供的接口是使用json格式来交互的;json格式是通过request的输入流来获取的; 所以发现的问题最终是组件的问题;

验证

  1. 定义拦截器

这个拦截器主要就是获取request中的数据;这里获取的是流中的数据,也可以获取Parameter中的数据;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class TestInterceptor extends HandlerInterceptorAdapter {
    private final Logger logger = LoggerFactory.getLogger(TestInterceptor.class);
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        BufferedReader reader = request.getReader();
        String line;
        StringBuilder sb = new StringBuilder();
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }
        logger.info("json信息:{}", sb.toString());
        return true;
    }
}
  1. 注册拦截器

注意这里并没有选择继承webmvcconfigureradapter ,因为webmvcconfigureradapter 已经标记废弃了; 所以用了另一种

1
2
3
4
5
6
7
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new TestInterceptor());
    }
}
  1. 构建控制器

这里主要是使用@RequestBody这个注解来接收请求数据;

1
2
3
4
5
6
7
8
9
10
11
@RestController
@RequestMapping("/test")
public class TestController {
    private final Logger logger= LoggerFactory.getLogger(TestController.class);
    @RequestMapping("/one")
    public String get(@RequestBody TestInfoVo testInfoVo){
        logger.info("controller 信息:{}",testInfoVo.toString());
        return "SUCCESS";
    }
}

最后

总结

  1. 请求的数据可以简单的分为两类;一类是数据是在request的Parameter中;一类是在request的输入流中;
  2. request的Parameter中的数据可以重复读取;
  3. request的输入流中的数据只可读取一次,如果要重复读取需要另外设置,但是数据读取一次就没了;
  4. 使用拦截器处理请求数据时,需考虑不同请求数据格式的问题;
坚持原创技术分享,您的支持将鼓励我继续创作!