我想记录所有 HTTP 请求。
通常,我可以使用以下代码获取成功请求的请求正文。
但是如果请求失败,我不会得到请求正文。
当我尝试获取失败请求的正文时,我只得到一个空字符串。
如何在java中获取失败的HTTP请求正文?
-过滤器类-
@Component
@Slf4j
public class HttpLogFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
long startTime = System.currentTimeMillis();
String requestId = UUID.randomUUID().toString();
response.addHeader(REQUEST_ID_PROPERTY_NAME, requestId);
ThreadContext.put(REQUEST_ID_PROPERTY_NAME, requestId);
ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request);
ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response);
filterChain.doFilter(requestWrapper, responseWrapper);
HttpLogDTO httpLog = collectHttpInfo(requestWrapper, responseWrapper);
responseWrapper.copyBodyToResponse();
long endTime = System.currentTimeMillis();
httpLog.setDuration(endTime - startTime);
log.info(httpLog.toString());
}
private HttpLogDTO collectHttpInfo(HttpServletRequest request, HttpServletResponse response) {
String scheme = request.getScheme();
String host = request.getServerName();
String port = String.valueOf(request.getLocalPort());
String path = request.getServletPath();
String parameters = request.getParameterMap().keySet().stream()
.map(key -> key + "=" + request.getParameterMap().get(key)[0]).collect(Collectors.joining("&"));
Map<String, List<String>> requestHeaders = Collections.list(request.getHeaderNames())
.stream()
.collect(Collectors.toMap(
Function.identity(),
h -> Collections.list(request.getHeaders(h))
));
Map<String, String> responseHeaders = response.getHeaderNames()
.stream()
.collect(Collectors.toMap(h -> h, response::getHeader));
return HttpLogDTO.builder()
.protocol(request.getProtocol())
.remote(request.getRemoteAddr())
.method(request.getMethod())
.uri(scheme + "://" + host + ":" + port + path + (StringUtils.isNotBlank(parameters) ? "?" + parameters : ""))
.host(host)
.path(path)
.scheme(scheme)
.port(port)
.requestHeaders(requestHeaders.toString())
.requestBody(new String(((ContentCachingRequestWrapper) request).getContentAsByteArray()))
.statusCode(String.valueOf(response.getStatus()))
.statusValue(Objects.requireNonNull(HttpStatus.resolve(response.getStatus())).getReasonPhrase())
.responseHeaders(responseHeaders.toString())
.responseBody(new String(((ContentCachingResponseWrapper) response).getContentAsByteArray()))
.build();
}
}
[解决了]
问题不在上面的 Filter 类中。
问题是我确实编写了代码,就像我不希望控制器类中的 body 一样。
在方法中添加带有 @RequestBody 注释的 POJO 类后问题解决了。
旧代码
@PostMapping("/post")
public ResponseEntity post() {
throw new BusinessValidationException(BusinessValidationRule.CITY_NOT_FOUND);
}
新代码
@PostMapping("/post")
public ResponseEntity post(@RequestBody Object body) {
throw new BusinessValidationException(BusinessValidationRule.CITY_NOT_FOUND);
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句