在控制器之前使用拦截器编辑对象的值

问题描述 投票:0回答:0

在请求到达控制器之前,是否有任何选项可以使用拦截器编辑值?

我尝试包装 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.

java spring-boot controller interceptor endpoint
© www.soinside.com 2019 - 2024. All rights reserved.