在请求到达控制器之前,是否有任何选项可以使用拦截器编辑值?
我尝试包装 HttpServletRequest 并设置新主体。
我在控制器中有 Post 请求,看起来像这样:
@PostMapping("/edit-via-interceptor")
public MyObject getNewObjectFromInterceptor(@RequestBody MyObject myObject){
return myObject;}
对象看起来像这样:
@Data
public class MyObject implements Serializable {
private List<String> ids;
}
RequestBody 有 id 列表,我想在拦截器中添加 2 个默认 id 到当前列表。
拦截器看起来像这样:
@Component
public class Interceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpServletRequest httpRequest = request;
CustomHttpServletRequestWrapper wrapper = new CustomHttpServletRequestWrapper(httpRequest);
ObjectMapper objectMapper = new ObjectMapper();
MyObject newMyObject = objectMapper.readValue(wrapper.getInputStream(), MyObject.class);
List<String> newIdsList = newMyObject.getIds();
newIdsList.add("123");
newIdsList.add("1234");
newMyObject.setIds(newIdsList);
byte[] data = SerializationUtils.serialize(newMyObject);
wrapper.setBody(data);
return super.preHandle(wrapper, response, handler);
}
}
CustomHttpServletRequestWrapper 看起来像这样:
public class CustomHttpServletRequestWrapper extends HttpServletRequestWrapper {
private byte[] body;
public CustomHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
try {
body = IOUtils.toByteArray(request.getInputStream());
} catch (IOException ex) {
body = new byte[0];
}
}
public void setBody(byte[] body){
this.body = body;
}
@Override
public ServletInputStream getInputStream() throws IOException {
return new ServletInputStream() {
ByteArrayInputStream bais = new ByteArrayInputStream(body);
@Override
public int read() throws IOException {
return bais.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener listener) {
}
};
}
}
拦截器模式的配置:
@Configuration
public class AuthConfig implements WebMvcConfigurer {
@Autowired
private Interceptor controllerInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// The registration of /api/** must be in the end
registry.addInterceptor(controllerInterceptor).addPathPatterns("/**);
}
毕竟,当涉及到控制器时 - MyObject 是 null.