springMvc filter 获取并打印参数

---恢复内容开始---

  今天领导安排给我一个活,在web.xml添加一个拦截器,日志打印出请求和响应的参数,搞了一下午,现在再次做一个笔记。

  先不急着上代码,我们先要理清整个http请求的逻辑,

  一次完整的HTTP请求过程从TCP三次握手建立连接成功后开始,客户端按照指定的格式开始向服务端发送HTTP请求,服务端接收请求后,解析HTTP请求,处理完业务逻辑,最后返回一个HTTP的响应给客户端,HTTP的响应内容同样有标准的格式。无论是什么客户端或者是什么服务端,大家只要按照HTTP的协议标准来实现的话,那么它一定是通用的。HTTP请求格式主要有四部分组成,分别是:请求行、请求头、空行、消息体,每部分内容占一行

  

  在看spring mvc的接收到参数并响应的过程:发送请求,委托请求给处理器,处理器在调用业务员对象,返回视图模型,返回视图给控制器,控制器在调用视图,返回给控制器,在返回给前台

  

  现在我们上代码:首先我们定义个人filter类

  


import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class UrlFilter implements Filter {

static Logger logger = LoggerFactory.getLogger(UrlFilter.class);

ServletContext context;

public void destroy() {
}

public void doFilter(ServletRequest request, ServletResponse response, FilterChain filter) throws IOException, ServletException {
HttpServletRequest r = (HttpServletRequest) request;
String path = r.getQueryString();
if (path == null) {
Map<String, String> map = new HashMap<String, String>();
Enumeration headerNames = ((HttpServletRequest) request).getHeaderNames();
while (headerNames.hasMoreElements()) {//循环遍历Header中的参数,把遍历出来的参数放入Map中
String key = (String) headerNames.nextElement();
String value = ((HttpServletRequest) request).getHeader(key);
map.put(key, value);
}
System.out.println(map.toString());
path = map.toString();
}
String url = r.getRequestURI();
RequestWrapper requestWrapper = null;
String repalceUrl = url.replaceAll("/", "");
if (null != repalceUrl) {
repalceUrl = repalceUrl.trim();
} else {
return;
}
logger.info(" ----------------- url:" + url + " & queryString:" + path);

ResponseWrapper responseWrapper = new ResponseWrapper((HttpServletResponse) response);

if (request instanceof HttpServletRequest) {
requestWrapper = new RequestWrapper((HttpServletRequest) request);
try {
Map map = request.getParameterMap();
logger.info("map:" + map);
BufferedReader bufferedReader = requestWrapper.getReader();
String line;
StringBuilder sb = new StringBuilder();
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
logger.info("request.getReader:" + sb.toString());
} catch (Exception e) {
// TODO: handle exception
logger.error("p2ps doFilter :", e);
}

}
if (null == requestWrapper) {
filter.doFilter(request, response);
} else {
filter.doFilter(requestWrapper, responseWrapper);
}

String result = new String(responseWrapper.getResponseData());

response.setContentLength(-1);//解决可能在运行的过程中页面只输出一部分
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.write(result);
out.flush();
out.close();
logger.info(" return data:" + result);
logger.info(" ---------------- end url:" + url + " httpstatus:" + ((HttpServletResponse) response).getStatus() + "");
}

public void init(FilterConfig filterConfig) throws ServletException {
context = filterConfig.getServletContext();
}

}
 

  再定义一个接收请求的处理类 

import com.demo.utils.StreamUtil;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;


/**
 * 复制request中的bufferedReader中的值
 *
 * @date 2016年9月1日  上午10:53:06
 */
public class RequestWrapper extends HttpServletRequestWrapper {

    private final byte[] body;

    /**
     * 这个必须加,复制request中的bufferedReader中的值
     *
     * @param request
     * @throws IOException
     */
    public RequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        //body = StreamUtil.readBytes(request.getReader(), "UTF-8");
        body = StreamUtil.getByteByStream(request.getInputStream());

    }

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

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

            public boolean isFinished() {
                return false;
            }

            public boolean isReady() {
                return false;
            }

            public void setReadListener(ReadListener readListener) {

            }

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

}
import java.io.ByteArrayOutputStream;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

public class ResponseWrapper extends HttpServletResponseWrapper {
    
    private ByteArrayOutputStream buffer = null;//输出到byte array
    private ServletOutputStream out = null;
    private PrintWriter writer = null;

    public ResponseWrapper(HttpServletResponse resp) throws IOException {
        super(resp);
        buffer = new ByteArrayOutputStream();// 真正存储数据的流
        out = new WapperedOutputStream(buffer);
        writer = new PrintWriter(new OutputStreamWriter(buffer, this.getCharacterEncoding()));
    }

    /** 重载父类获取outputstream的方法 */
    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        return out;
    }

    /** 重载父类获取writer的方法 */
    @Override
    public PrintWriter getWriter() throws UnsupportedEncodingException {
        return writer;
    }

    /** 重载父类获取flushBuffer的方法 */
    @Override
    public void flushBuffer() throws IOException {
        if (out != null) {
            out.flush();
        }
        if (writer != null) {
            writer.flush();
        }
    }

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

    /** 将out、writer中的数据强制输出到WapperedResponse的buffer里面,否则取不到数据 */
    public byte[] getResponseData() throws IOException {
        flushBuffer();
        return buffer.toByteArray();
    }

    /** 内部类,对ServletOutputStream进行包装 */
    private class WapperedOutputStream extends ServletOutputStream {
        private ByteArrayOutputStream bos = null;

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

        @Override
        public void write(int b) throws IOException {
            bos.write(b);
        }

        @Override
        public void write(byte[] b) throws IOException {
            bos.write(b, 0, b.length);
        }

        public boolean isReady() {
            return false;
        }

        public void setWriteListener(WriteListener writeListener) {

        }
    }

}

   在web.xml 中添加刚编写的自定义filter类

    <filter>
        <filter-name>UrlFilter</filter-name>
        <filter-class>com.demo.demo2.UrlFilter</filter-class><!--注意,此路径换成您自己项目的路径-->
    </filter>
    <filter-mapping>
        <filter-name>UrlFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

  在编写一个contrller 测试调用就ok了。

  写的不好请海涵,有错的地方请留言,我及时更正

  下面是我参考的文章路径:http://www.voidcn.com/blog/wuhenzhangxing/article/p-6299832.html

              http://blog.jobbole.com/106632/

              

 

---恢复内容结束---

原文地址:https://www.cnblogs.com/xincunyiren/p/7248034.html