Spring Boot应用程序过滤器响应主体

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

我正在开发Spring Boot应用程序。我想通过请求正文字段“ Id”修改请求的响应。

我已经在下面实现了,但是在实现时仍会在输出中得到名称。任何在下面实现的建议都会有所帮助:

下面是requestBody:

{
"id" : "123"
}

作为响应,我想将该字段附加到响应ID(请求主体的字段名)。responseBody:

{
"name" : "foo123"  //name + id from request
}

MyCustomFilter:

public class TestFilter implements Filter {


    @Override
    public void doFilter(
            ServletRequest request,
            ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
       HttpServletResponse res = (HttpServletResponse) response;
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    final PrintStream ps = new PrintStream(baos);
    MultiReadHttpServletRequest wrapper = new MultiReadHttpServletRequest((HttpServletRequest) request);

    MyRequestWrapper req = new MyRequestWrapper(wrapper);
    String userId = req.getId();

    chain.doFilter(wrapper, new HttpServletResponseWrapper(res) {
        @Override
        public ServletOutputStream getOutputStream() throws IOException {
            return new DelegatingServletOutputStream(new TeeOutputStream(super.getOutputStream(), ps)
            );
        }

        @Override
        public PrintWriter getWriter() throws IOException {
            return new PrintWriter(new DelegatingServletOutputStream(new TeeOutputStream(super.getOutputStream(), ps))
            );
        }
    });

    String responseBody = baos.toString();

    ObjectMapper mapper = new ObjectMapper();
    JsonNode node = mapper.readTree(responseBody);
    String name = node.get("name").astext();

    ((ObjectNode) node1).put("name", name + userId);

    chain.doFilter(wrapper, res);
}

MyRequestWrapper:

public class MyRequestWrapper extends HttpServletRequestWrapper {
    private ServletInputStream input;

    public MyRequestWrapper(ServletRequest request) {
        super((HttpServletRequest)request);
    }

    public String getId() throws IOException {
        if (input == null) {
            try {
                JSONObject jsonObject = new JSONObject(IOUtils.toString(super.getInputStream()));
                String userId = jsonObject.getString("id");

                userId = userId.replaceAll("\\D+","");
                return userId;
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

MultiReadHttpServletRequest.java

public class MultiReadHttpServletRequest extends HttpServletRequestWrapper {

private byte[] body;

public MultiReadHttpServletRequest(HttpServletRequest request) {
    super(request);
    try {
        body = IOUtils.toByteArray(request.getInputStream());
    } catch (IOException ex) {
        body = new byte[0];
    }
}

@Override
public BufferedReader getReader() throws IOException {
    return new BufferedReader(new InputStreamReader(getInputStream(), getCharacterEncoding()));
}

@Override
public ServletInputStream getInputStream() throws IOException {
    return new ServletInputStream() {
        ByteArrayInputStream wrapperStream = new ByteArrayInputStream(body);

        @Override
        public boolean isFinished() {
            return false;
        }

        @Override
        public boolean isReady() {
            return false;
        }

        @Override
        public void setReadListener(ReadListener readListener) {

        }

        @Override
        public int read() throws IOException {
            return wrapperStream.read();
        }
    };
}

}

任何建议都值得赞赏。 TIA。Nte:更新后,我看不到更新后的响应作为输出。我仍然只看到名称,但未附加ID。

spring spring-boot filter httpresponse servlet-filters
1个回答
0
投票

我在自己的ServletRequest实现中看到的一个问题是,您调用super.getInputStream()而不是request.getInputStream()。默认情况下,您自己的请求为空,这就是为什么您超时超时的原因。您必须将呼叫委派给实际的请求:

public class MyRequestWrapper extends HttpServletRequestWrapper {
    private ServletInputStream input;

    public MyRequestWrapper(ServletRequest request) {
        super((HttpServletRequest)request);
    }

    public String getId() throws IOException {
        if (input == null) {
            try {
                JSONObject jsonObject = new JSONObject(IOUtils.toString(/*DELETEGATE TO ACTUAL REQUEST*/request.getInputStream()));
                String userId = jsonObject.getString("id");

                userId = userId.replaceAll("\\D+","");
                return userId;
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.