龙空技术网

JavaEE中统一修改http响应体内容的方法

向上生长之路 103

前言:

眼前大家对“java中的modify”大致比较着重,你们都需要剖析一些“java中的modify”的相关内容。那么小编在网摘上收集了一些有关“java中的modify””的相关资讯,希望咱们能喜欢,大家快快来了解一下吧!

在之前的文章中介绍过Spring Boot开发中统一修改http响应体内容的方法

spring-boot中统一修改http响应体内容的方法

今天给大家再介绍另一种方案也能实现同样的效果,那就是JavaEE中通过使用Filter过滤器来修改http响应体~

工作原理

JavaEE中提供了HttpServletResponseWrapper,该类实现了HttpServletResponse接口,通过重写该类的getOutputStream、getWriter方法来拦截Servlet响应内容,结合Filter的使用,就可以在Filter中统一修改http响应体了

JavaEE官方文档说明:

使用方式

1.编写HttpServletResponseWrapper的实现类,来包装HttpServletResponse,等下在Filter中会用于替换真正的HttpServletResponse对象

示例代码:

public class ModifyHttpResponseWrapper extends HttpServletResponseWrapper {    private CharArrayWriter bufferWriter;    private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();    private HttpServletResponse httpServletResponse;    public ModifyHttpResponseWrapper(HttpServletResponse response) {        super(response);        bufferWriter = new CharArrayWriter();        httpServletResponse = response;    }    @Override    public ServletOutputStream getOutputStream() {        return new ServletOutputStreamWrapper(this.byteArrayOutputStream, this.httpServletResponse);    }    @Override    public PrintWriter getWriter() throws IOException {        return new PrintWriter(bufferWriter);    }    public String getResult() {        return bufferWriter.toString();    }    public String getContent() {        return new String(byteArrayOutputStream.toByteArray());    }    @Override    public void setContentType(String type) {        super.setContentType(type);    }    private class ServletOutputStreamWrapper extends ServletOutputStream {        private ByteArrayOutputStream outputStream;        private HttpServletResponse response;        public ServletOutputStreamWrapper(ByteArrayOutputStream byteArrayOutputStream, HttpServletResponse response) {            this.outputStream = byteArrayOutputStream;            this.response = response;        }        @Override        public boolean isReady() {            return true;        }        @Override        public void setWriteListener(WriteListener listener) {        }        @Override        public void write(int b) throws IOException {            this.outputStream.write(b);        }        @Override        public void flush() throws IOException {            if (!this.response.isCommitted()) {                byte[] body = this.outputStream.toByteArray();                ServletOutputStream outputStream = this.response.getOutputStream();                outputStream.write(body);                outputStream.flush();            }        }    }}

2.编写Filter过滤器来拦截http响应,达到最终修改http响应体的目的

示例代码:

@WebFilter(filterName = "ModifyHttpResponseFilter", urlPatterns = {"/json/*"})public class ModifyHttpResponseFilter implements Filter {    @Override    public void init(FilterConfig filterConfig) throws ServletException {    }    @Override    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {        HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;        ModifyHttpResponseWrapper modifyHttpResponseWrapper = new ModifyHttpResponseWrapper(httpServletResponse);        System.out.println("-----------------before ModifyHttpResponseFilter------------------");        filterChain.doFilter(servletRequest, modifyHttpResponseWrapper);        System.out.println("-----------------after ModifyHttpResponseFilter------------------");        JSONObject jsonObject = JSON.parseObject(StringUtils.isBlank(modifyHttpResponseWrapper.getResult()) ? modifyHttpResponseWrapper.getContent() : modifyHttpResponseWrapper.getResult());        jsonObject.put("msg", "wrapper[" + jsonObject.getString("msg") + "]");        HttpServletResponse response = (HttpServletResponse) modifyHttpResponseWrapper.getResponse();        response.setContentType("application/json; charset=UTF-8");        PrintWriter printWriter = response.getWriter();        printWriter.write(jsonObject.toJSONString());        printWriter.flush();        printWriter.close();    }    @Override    public void destroy() {    }}

3.编写测试用的Servlet,来测试http响应体改写情况

完整示例代码:

@WebServlet(name = "jsonServlet", urlPatterns = {"/json"})public class JSONServlet extends HttpServlet {    @Override    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        JSONObject data = new JSONObject();        data.put("success", true);        data.put("msg", "invoke success for " + this.getClass().getName());        System.out.println("get json=" + data);        response.getWriter().write(data.toString());    }}
运行效果

启动工程,使用Postman工具访问/json接口测试

可以看到返回的数据中已经被wrapper[]包装了

请求执行流程

完整测试工程请参考:

明白了原理,JavaEE中的这种机制我们完全可以用在Spring Boot开发中~

示例伪代码:

     //注册Filter过滤器来拦截响应内容,并修改最终的响应体    @Bean    public FilterRegistrationBean registration() {        FilterRegistrationBean registration = new FilterRegistrationBean();        //注册        registration.setFilter(new YourFilter());        registration.addUrlPatterns("/YourPath/*");        registration.setOrder(1000);        return registration;    }

示例过滤器,在doFilter中做自定义的逻辑处理,可以达到统一修改http响应体的效果~

  public class YourFilter extends GenericFilterBean {    @Override    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {       //todo 自定义处理逻辑    }  }

完整代码写法可以参考我在spring-boot-admin issue中的回答:

标签: #java中的modify