SpringMVC拦截器踩坑日记
前言
情景回顾:
最近和第三方一起调试接口,对方总是说调用我们的接口报重复提交的问题;
而我们关于重复提交的这个是一个统一的基础组件;所以事先排除了这个基础组件的问题;
最后经过排查,发现这个组件是从request的Parameter中获取的数据用来判断是否二次提交的,而这种方式是取不到json格式的数据的;
然而我们对外提供的接口是使用json格式来交互的;json格式是通过request的输入流来获取的;
所以发现的问题最终是组件的问题;
验证
- 定义拦截器
这个拦截器主要就是获取request中的数据;这里获取的是流中的数据,也可以获取Parameter中的数据;
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;
}
}
- 注册拦截器
注意这里并没有选择继承webmvcconfigureradapter
,因为webmvcconfigureradapter
已经标记废弃了;
所以用了另一种
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new TestInterceptor());
}
}
- 构建控制器
这里主要是使用@RequestBody这个注解来接收请求数据;
@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";
}
}
最后
总结
- 请求的数据可以简单的分为两类;一类是数据是在request的Parameter中;一类是在request的输入流中;
- request的Parameter中的数据可以重复读取;
- request的输入流中的数据只可读取一次,如果要重复读取需要另外设置,但是数据读取一次就没了;
- 使用拦截器处理请求数据时,需考虑不同请求数据格式的问题;