キーワード:
リクエストパラメータ、応答パラメータ、フィルター、インターセプター、ログフィルタは、フィルタに設定され
I.目的:
システムパラメータ、印刷出力の要求と応答のパラメータ。サポートフォームの送信とJSONを提出します。
第二に、フィルタおよびインターセプタ
まず、フィルタやインターセプタを見てください。両方の機能は非常に似ていますが、特定の技術、程遠いです。2間の前の差に比べると、最初の何AOPを理解し、AOPは、特定の技術ではなく、プログラミングのアイデア。オブジェクト指向プログラミングの過程では、我々は簡単継承によって、多型は、スケールアップを解決することができます。しかし、のような横方向の機能のために、開いているすべてのトランザクションサービス法など統合ログ機能では、オブジェクト指向を解決することはできません。だから、AOP--指向プログラミングは、実際に相補的な標的指向プログラミングのアイデアです。そして、我々は今日のフィルターの話とインターセプタは、アスペクト指向プログラミングのすべての具体的な実現しています。2つの主な違いは、次のものがあります。
図1に示すように、フィルタは、サーブレット仕様の一部に属する、サーブレットコンテナに依存して、インターセプターは、独立した存在であり、いずれの場合にも使用することができます。
図2に示すように、実行フィルタコールバック・サーブレットコンテナによって完成される。インターセプタは、典型的には、動的プロキシによって実行されます。
図3に示すように、フィルタのライフサイクルは、サーブレットコンテナによって管理される。インターセプタは、IoCコンテナによって管理することができ、したがって、他の実施例は、等、ビーンを注入することによって得ることができるので、使用する方が便利であろう。
第三に、ログフィルタ_コード
import com.alibaba.fastjson.JSON;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
/**
* json请求时,如果body包含header,则剥除
* 顺便 输出对应url 请求体,响应体,耗时
*/
public class LogFilter extends OncePerRequestFilter {
private static final Logger log = LoggerFactory.getLogger(LogFilter.class);
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
long requestTime = System.currentTimeMillis();
String uri = request.getRequestURI();
String contextPath = request.getContextPath();
String url = uri.substring(contextPath.length());
//静态资源 跳过
if (url.contains(".")) {
filterChain.doFilter(request, response);
return;
}
// 输出请求体
String requestBody = "";
String requestContentType = request.getHeader(HttpHeaders.CONTENT_TYPE);
if (requestContentType != null){
// xml json
if (requestContentType.startsWith(MediaType.APPLICATION_JSON_VALUE) || requestContentType.startsWith(MediaType.APPLICATION_XML_VALUE)){
requestBody = getRequestBody(request);
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(requestBody.getBytes(StandardCharsets.UTF_8));
request = new HttpServletRequestWrapper(request) {
@Override
public ServletInputStream getInputStream() throws IOException {
return new ByteArrayServletInputStream(byteArrayInputStream);
}
};
// 普通表单提交
}else if (requestContentType.startsWith(MediaType.APPLICATION_FORM_URLENCODED_VALUE)){
requestBody = toJson(request.getParameterMap());
// 文件表单提交
}else if (requestContentType.startsWith(MediaType.MULTIPART_FORM_DATA_VALUE)){
requestBody = getFormParam(request);
}
}
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
response = new HttpServletResponseWrapper(response) {
@Override
public ServletOutputStream getOutputStream() throws IOException {
return new TeeServletOutputStream(super.getOutputStream(), byteArrayOutputStream);
}
};
filterChain.doFilter(request, response);
long costTime = System.currentTimeMillis() - requestTime;
String responseBody = "";
// 暂定只有json 输出响应体
String contentType = response.getHeader(HttpHeaders.CONTENT_TYPE);
if (contentType != null && contentType.startsWith(MediaType.APPLICATION_JSON_VALUE)){
responseBody = byteArrayOutputStream.toString();
}
if (response.getStatus() >= 200 && response.getStatus() < 300) {
log.info("URL:{}, total time:{} ms, responseCode:{}, requestBody:{}, responseBody:{}", url, costTime, response.getStatus(), requestBody, responseBody);
}else {
log.error("URL:{}, total time:{} ms, responseCode:{}, requestBody:{}, responseBody:{}", url, costTime, response.getStatus(), requestBody, responseBody);
}
}
private String getRequestBody(HttpServletRequest request) {
int contentLength = request.getContentLength();
if(contentLength <= 0){
return "";
}
try {
return IOUtils.toString(request.getReader());
} catch (IOException e) {
log.error("获取请求体失败", e);
return "";
}
}
private String getFormParam(HttpServletRequest request) {
MultipartResolver resolver = new StandardServletMultipartResolver();
MultipartHttpServletRequest mRequest = resolver.resolveMultipart(request);
Map<String,Object> param = new HashMap<>();
Map<String,String[]> parameterMap = mRequest.getParameterMap();
if (!parameterMap.isEmpty()){
param.putAll(parameterMap);
}
Map<String, MultipartFile> fileMap = mRequest.getFileMap();
if(!fileMap.isEmpty()){
for (Map.Entry<String, MultipartFile> fileEntry : fileMap.entrySet()) {
MultipartFile file = fileEntry.getValue();
param.put(fileEntry.getKey(), file.getOriginalFilename()+ "(" + file.getSize()+" byte)");
}
}
return toJson(param);
}
private static String toJson(Object object){
return JSON.toJSONStringWithDateFormat(object, "yyyy-MM-dd HH:mm:ss");
}
}
ご注意くださいコード:FilterChain.doFilter(要求、応答);
その方法は、タイムスタンプ、及び要求パラメータを記録する前に行われ、その後、フィルタ・チェーンによる要求の実行の完了は、収集した応答パラメータの後、算出された印刷の間に実行結果を返します。
四、配置されたフィルタ_コード
import com.myfutech.common.spring.filter.LogFilter;
import com.myfutech.common.spring.filter.UserInfoFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean logFilter() {
final FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
final LogFilter logFilter = new LogFilter();
filterRegistrationBean.setFilter(logFilter);
return filterRegistrationBean;
}
}
参考:
https://www.cnblogs.com/paddix/p/8365558.html