spring - 如何设置 OncePerRequestFilter 的实现以仅过滤一个端点
问题描述
我使用这个过滤器来记录我的请求和响应,它工作得很好,但我注意到我实际上不需要为我的所有端点使用这个过滤器——它会更有效,并且足以过滤和记录来自一个端点的请求。是否可以在方法中不使用 if 语句afterRequest
?我搜索了很多,但几乎每个示例都与 spring security :(
@Slf4j
@Component
public class RequestAndResponseLoggingFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
if (isAsyncDispatch(request)) {
filterChain.doFilter(request, response);
} else {
doFilterWrapped(wrapRequest(request), wrapResponse(response), filterChain);
}
}
protected void doFilterWrapped(ContentCachingRequestWrapper request, ContentCachingResponseWrapper response, FilterChain filterChain) throws ServletException, IOException {
beforeRequest(request, response);
try {
filterChain.doFilter(request, response);
}
finally {
afterRequest(request, response);
response.copyBodyToResponse();
}
}
protected void beforeRequest(ContentCachingRequestWrapper request, ContentCachingResponseWrapper response) {
if (log.isInfoEnabled()) {
val address = request.getRemoteAddr();
val queryString = request.getQueryString();
if (queryString == null) {
log.info("{}> {} {}", address, request.getMethod(), request.getRequestURI());
} else {
log.info("{}> {} {}?{}", address, request.getMethod(), request.getRequestURI(), queryString);
}
Collections.list(request.getHeaderNames()).forEach(headerName ->
Collections.list(request.getHeaders(headerName)).forEach(headerValue ->
log.info("{}> {}: {}", address, headerName, headerValue)));
val content = request.getContentAsByteArray();
if (content.length > 0) {
log.info("{}>", address);
try {
val contentString = new String(content, request.getCharacterEncoding());
Stream.of(contentString.split("\r\n|\r|\n")).forEach(line -> log.info("{}> {}", address, line));
} catch (UnsupportedEncodingException e) {
log.info("{}> [{} bytes body]", address, content.length);
}
}
log.info("{}>", address);
}
}
protected void afterRequest(ContentCachingRequestWrapper request, ContentCachingResponseWrapper response) {
if (log.isInfoEnabled()) {
val address = request.getRemoteAddr();
val status = response.getStatus();
log.info("{}< {} {}", address, status, HttpStatus.valueOf(status).getReasonPhrase());
response.getHeaderNames().forEach(headerName ->
response.getHeaders(headerName).forEach(headerValue ->
log.info("{}< {}: {}", address, headerName, headerValue)));
val content = response.getContentAsByteArray();
if (content.length > 0) {
log.info("{}<", address);
try {
val contentString = new String(content, request.getCharacterEncoding());
Stream.of(contentString.split("\r\n|\r|\n")).forEach(line -> log.info("{}< {}", address, line));
} catch (UnsupportedEncodingException e) {
log.info("{}< [{} bytes body]", address, content.length);
}
}
}
}
private static ContentCachingRequestWrapper wrapRequest(HttpServletRequest request) {
if (request instanceof ContentCachingRequestWrapper) {
return (ContentCachingRequestWrapper) request;
} else {
return new ContentCachingRequestWrapper(request);
}
}
private static ContentCachingResponseWrapper wrapResponse(HttpServletResponse response) {
if (response instanceof ContentCachingResponseWrapper) {
return (ContentCachingResponseWrapper) response;
} else {
return new ContentCachingResponseWrapper(response);
}
}
}
解决方案
推荐阅读
- android - 对长按执行波纹效果
- reactjs - 如何查找在特定时间范围内单击按钮的次数(0.5秒内)
- html - 使用 VBA 在导出的 HTML 表中添加超链接
- tfs - 由于重复的 ProjectGuid,没有对 dotnet Core 项目进行 SonarQube 分析
- javascript - 使用 div id 遍历列表
- error-handling - 向订阅 RXJS 发送错误
- java - 将长列表转换为字符串集
- azure - 执行 DownloadToFIleParallelAsync 方法时的问题
- java - Java:确定两个正则表达式模式是否重叠
- node.js - 带有heroku的axios