通过拦截器或者过滤器获取response携带的数据

  • Post author:
  • Post category:其他



记一次在实际项目中获取response中数据的经历,由于某些原因不能讲公司代码公开,此处代码仅为本人练习所用



一、拦截器方式

在springMVC4版本以后,新加了一个@ControllerService注解。用此注解然后实现ResponseBodyAdvice接口可获取带有@responsebody的返回值。

package com.wangxu.interceptor;

import com.wangxu.result.Result;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import javax.servlet.http.HttpServletResponse;

/**
 * @author wx
 * @Description:
 * @Title:
 * @Package
 * @date 2021/2/8 11:22
 */
@ControllerAdvice
public class getResponseAdvice implements ResponseBodyAdvice<Object> {
    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
        return true;
    }

    /**
     * @Description: 该方法是拦截到返回值(即response中的数据),然后操作返回值,并返回
     *
     **/
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        System.out.println("进入beforeBodyWrite方法");
        ServletServerHttpResponse responseTemp = (ServletServerHttpResponse) serverHttpResponse;
        HttpServletResponse response = responseTemp.getServletResponse();
        if (body instanceof Result) {
            Result result = (Result) body;
            Object data = result.getMessage();
            System.out.println(data.toString());
        }
        return body;
    }
}

下图为拦截的controller接口

在这里插入图片描述

获取到的数据

在这里插入图片描述



二、过滤器filter方式


1、 在启动类上加@ServletComponentScan注解


在这里插入图片描述


2、新建过滤器

这个过滤器使用了注解@WebFilter(filterName = “getReponseFilter”, urlPatterns = {“/user/hello”}),指定了url进入规则,只有该url才能进入到此过滤器中。在doFilter方法中使用了自定义的ResponseWrapper对response进行封装。Controller接口走完之后获取到接口返回的数据并再次封装到response。

package com.wangxu.filter;

import com.alibaba.fastjson.JSONObject;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author wx
 * @Description:
 * @Title:
 * @Package
 * @date 2021/2/8 11:40
 */

@WebFilter(filterName = "getReponseFilter", urlPatterns = {"/user/hello"})
public class getReponseFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        ResponseWrapper wrapper = new ResponseWrapper((HttpServletResponse) response);
        HttpServletRequest req = (HttpServletRequest) request;

        chain.doFilter(request, wrapper);
        // 获取response返回的内容并重新写入response, 若获取到的数据是乱码,可设置response的编码为系统默认编码集
        String result = wrapper.getResponseData(response.getCharacterEncoding());
        Object object = JSONObject.parse(result);
        response.getOutputStream().write(result.getBytes());
        response.getOutputStream().flush();
        response.getOutputStream().close();


    }

    @Override
    public void destroy() {

    }
}


3、ResponseWrapper.java 类

package com.wangxu.filter;

import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.*;

/**
 * @author wx
 * @Description:
 * @Title:
 * @Package
 * @date 2021/2/8 11:44
 */
public class ResponseWrapper extends HttpServletResponseWrapper {

    private ByteArrayOutputStream buffer = null;

    private ServletOutputStream out = null;

    private PrintWriter writer = null;

    public ResponseWrapper(HttpServletResponse response) throws IOException {
        super(response);
        buffer = new ByteArrayOutputStream();
        out = new WapperedOutputStream(buffer);
        writer = new PrintWriter(new OutputStreamWriter(buffer, "UTF-8"));
    }

    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        return out;
    }

    @Override
    public PrintWriter getWriter() throws IOException {
        return writer;
    }

    @Override
    public void flushBuffer() throws IOException {
        if (out != null) {
            out.flush();
        }
        if (writer != null) {
            writer.flush();
        }
    }

    @Override
    public void reset() {
        buffer.reset();
    }

    /**
     * @Description: 获取response中数据的方法
     *
     * @param charset charset
     * @return java.lang.String
     * @author 王旭
     * @date 2021/2/8 11:48
     **/
    public String getResponseData(String charset) throws IOException {
        flushBuffer();//将out、writer中的数据强制输出到WapperedResponse的buffer里面,否则取不到数据
        byte[] bytes = buffer.toByteArray();
        try {
            return new String(bytes, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            return "";
        }

    }


    //内部类,对ServletOutputStream进行包装,指定输出流的输出端
    private class WapperedOutputStream extends ServletOutputStream {

        private ByteArrayOutputStream bos = null;

        public WapperedOutputStream(ByteArrayOutputStream stream) throws IOException {
            bos = stream;
        }

        //将指定字节写入输出流bos
        @Override
        public void write(int b) throws IOException {
            bos.write(b);
        }

        @Override
        public boolean isReady() {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public void setWriteListener(WriteListener listener) {
            // TODO Auto-generated method stub

        }
    }

}


下图是debug获取response中数据的结果


在这里插入图片描述

参考文章:


https://zhuanlan.zhihu.com/p/75243950


https://blog.csdn.net/a582127421/article/details/78321888?ops_request_misc=%25257B%252522request%25255Fid%252522%25253A%252522161275872516780299080584%252522%25252C%252522scm%252522%25253A%25252220140713.130102334…%252522%25257D&request_id=161275872516780299080584&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2

all

first_rank_v2~rank_v29-1-78321888.pc_search_result_hbase_insert&utm_term=springboot+%25E4%25BD%25BF%25E7%2594%25A8%25E8%25BF%2587%25E6%25BB%25A4%25E5%2599%25A8%25E8%258E%25B7%25E5%258F%2596response%25E5%2586%2585%25E5%25AE%25B9



版权声明:本文为mengshangwangzi原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。