在 spring mvc 中使用 servlet 过滤器将现有响应替换为新响应

vip*_* cp 2 java json servlets spring-mvc filter

我想json使用过滤器将现有响应(在某些情况下)替换为新响应。我想做的是JSON从过滤器读取现有的响应()。使用新值修改它并写回响应。但结果显示两者都有反应。

也就是说,我从回复中读到的内容以及我新添加的内容。但我需要用新的响应替换旧的响应。下面添加了代码。

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
{
    try{
     ByteArrayOutputStream baos = new ByteArrayOutputStream();
        final PrintStream ps = new PrintStream(baos);

        chain.doFilter(request,new HttpServletResponseWrapper((HttpServletResponse)response) {
               @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))
                );
             }
          });
        /* get existing response as string*/
        String respopn=baos.toString(); 
        JSONObject json=new JSONObject(respopn);
        JSONObject dMap=new JSONObject(json.get("dataMap"));
        dMap.put("new", "newValue");
        json.put("dataMap", dMap); // Modified the old datamap with new json
        JsonMapper jsonMap=new JsonMapper();
        jsonMap.setJson(json);
        String str=jsonMap.getJson();
        byte[] responseToSend = restResponseBytes(jsonMap);
        response.getOutputStream().write(responseToSend); // write to response only the new one



    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
    }


   private byte[] restResponseBytes(Object response) throws IOException {
        String serialized = new ObjectMapper().writeValueAsString(response);
        return serialized.getBytes();
    }
Run Code Online (Sandbox Code Playgroud)

小智 5

我觉得下面的代码片段应该可以工作。上面的问题是它被附加到现有数据而不是重写。我们需要创建一个数据存储位置的副本,并在操作原始 ServletResponse 后进行复制。希望下面的代码片段可以解决您的问题。

下面是主要做过滤的方法-

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

    ServletResponseWrapperCopier capturingResponseWrapper = new ServletResponseWrapperCopier(
                (HttpServletResponse) response);

    chain.doFilter(request, capturingResponseWrapper);
    try{
        String respopn = capturingResponseWrapper.getCaptureAsString();     
        JSONObject json=new JSONObject(respopn);
        JSONObject dMap=new JSONObject(json.get("dataMap"));
        dMap.put("new", "newValue");
        json.put("dataMap", dMap); // Modified the old datamap with new json
        JsonMapper jsonMap=new JsonMapper();
        jsonMap.setJson(json);
        String str=jsonMap.getJson();
        response.getOutputStream().write(str.getBytes());
    } catch(Exception e){
        log.error("");
    }
}
Run Code Online (Sandbox Code Playgroud)

下面的类用于复制上面代码片段中的 ServletResponse

public class ServletResponseWrapperCopier extends HttpServletResponseWrapper{

private final ByteArrayOutputStream capture;
private ServletOutputStream output;
private PrintWriter writer;

public ServletResponseWrapperCopier(HttpServletResponse response) {
    super(response);
    capture = new ByteArrayOutputStream(response.getBufferSize());
}

@Override
public ServletOutputStream getOutputStream() {
    if (writer != null) {
        throw new IllegalStateException(
                "getWriter() has already been called on this response.");
    }

    if (output == null) {
        output = new ServletOutputStream() {
            @Override
            public void write(int b) throws IOException {
                capture.write(b);
            }

            @Override
            public void flush() throws IOException {
                capture.flush();
            }

            @Override
            public void close() throws IOException {
                capture.close();
            }
        };
    }

    return output;
}

@Override
public PrintWriter getWriter() throws IOException {
    if (output != null) {
        throw new IllegalStateException(
                "getOutputStream() has already been called on this response.");
    }

    if (writer == null) {
        writer = new PrintWriter(new OutputStreamWriter(capture,
                getCharacterEncoding()));
    }

    return writer;
}

public byte[] getCaptureAsBytes() throws IOException {
    if (writer != null) {
        writer.close();
    } else if (output != null) {
        output.close();
    }

    return capture.toByteArray();
}

public String getCaptureAsString() throws IOException {
    return new String(getCaptureAsBytes(), getCharacterEncoding());
}
Run Code Online (Sandbox Code Playgroud)

}