gpt4 book ai didi

java - 如何使用java过滤器修改响应主体?

转载 作者:行者123 更新时间:2023-12-01 22:19:01 24 4
gpt4 key购买 nike

我想对 HTTP 响应(json 格式)执行一些过滤逻辑。

我已成功更改响应正文,但是当正文的(字符串)大小发生变化时:我丢失了最后一个字符。

为了更简单,我创建了一个简单的 Spring Boot 应用程序,仅对我的其余 Controller 进行 Web 依赖。

我的休息 Controller

@RestController
@RequestMapping("/home/")
public class RestControllerHome {

@GetMapping (produces=MediaType.APPLICATION_JSON_VALUE)
public String home() {
return "{ \"name\" : \"Peter\" }";
}
}

我的过滤器

@Component
public class MyFilter implements Filter {

@Override
public void destroy() { }

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {

HtmlResponseWrapper capturingResponseWrapper = new HtmlResponseWrapper((HttpServletResponse) response);
filterChain.doFilter(request, capturingResponseWrapper);
if (response.getContentType() != null && response.getContentType().contains("application/json")) {
String content = capturingResponseWrapper.getCaptureAsString();

// This code works fine
//response.getWriter().write(content.toUpperCase());

// This code doesn't works because the content size is changed
response.getWriter().write("{ \"name\" : \"************r\" }");

}
}

@Override
public void init(FilterConfig arg0) throws ServletException { }
}

HttpServletResponseWrapper //在写入之前捕获响应

public class HtmlResponseWrapper extends HttpServletResponseWrapper {

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

public HtmlResponseWrapper(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) {
// inner class - lets the wrapper manipulate the response
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();
}

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

@Override
public void setWriteListener(WriteListener arg0) {
}
};
}

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;
}

@Override
public void flushBuffer() throws IOException {
super.flushBuffer();

if (writer != null) {
writer.flush();
} else if (output != null) {
output.flush();
}
}

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());
}

}

在我的doFilter方法中,以下代码...

// This code works fine
response.getWriter().write(content.toUpperCase());

// This code doesn't works because the content size is changed
//response.getWriter().write("{ \"name\" : \"************r\" }");

...给出了以下输出:{"NAME": "PETER"}这告诉我,代码工作正常。

但是,实际上我想更改正文内容......

// This code works fine
//response.getWriter().write(content.toUpperCase());

// This code doesn't works because the content size is changed
response.getWriter().write("{ \"name\" : \"************r\" }");

...以及前面的代码,给我一个不完整的文本正文作为输出:**{“姓名”:“************

我做错了什么?我的应用程序有一个更大的 json 主体,并且过滤器中的逻辑更复杂一些。但是,如果我不能让这个工作,我就无法让我的代码的其余部分工作。请帮忙。

我从 https://www.leveluplunch.com/java/tutorials/034-modify-html-response-using-filter/ 获取了 Filter 和 HttpServletResponseWrapper

最佳答案

感谢JBNizet的帮助,我发现解决方案是添加Content Lenght:

String newContent = "{ \"name\" : \"************r\" }";
response.setContentLength(newContent .length());
response.getWriter().write(newContent);

关于java - 如何使用java过滤器修改响应主体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51826475/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com