【发布时间】:2021-10-08 15:57:05
【问题描述】:
我正在尝试使用自定义记录器类记录请求和响应。在我开始收到具有“多部分/数据”类型的 Http 请求之前,这一切都运行良好。
从那时起,所有发送的“多部分/数据”类型都引发错误并且无法正常运行。
我首先收到一条错误消息:无法处理部件,因为没有提供多部件配置
所以我尝试获取那些特定的多部分响应并以不同的方式管理它们,但无济于事。我删除了 super.doDispatcher(req, res) 我不确定这是正确的方法。
这是我的记录器类:
public class LoggableDispatcherServlet extends DispatcherServlet {
private final Log logger = LogFactory.getLog(getClass());
@Override
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
if (!(request instanceof ContentCachingRequestWrapper)) {
request = new ContentCachingRequestWrapper(request);
}
if (!(response instanceof ContentCachingResponseWrapper)) {
response = new ContentCachingResponseWrapper(response);
}
HandlerExecutionChain handler = getHandler(request);
boolean mulipart = false;
try {
if (request.getContentType() != null && request.getContentType().toLowerCase().contains("multipart/form-data")){
logger.info("MULTIPART FILE RECEIVED");
mulipart = true;
}else
super.doDispatch(request, response);
}catch(Exception e){
logger.error(e.getMessage(), e);
}finally {
if (mulipart){
response = new ContentCachingResponseWrapper(response);
log(request, null, handler);
updateResponse(response);
} else {
log(request, response, handler);
updateResponse(response);
}
}
}
private void log(HttpServletRequest requestToCache, HttpServletResponse responseToCache, HandlerExecutionChain handler) {
LogMessage log = new LogMessage();
log.setHttpMethod(requestToCache.getMethod());
log.setUrl(requestToCache.getRequestURI());
log.setClientIp(requestToCache.getRemoteAddr());
log.setJavaMethod(handler.toString());
if(responseToCache != null){
log.setHttpStatus(responseToCache.getStatus());
log.setResponse(getResponsePayload(responseToCache));
}
logger.info(log);
}
private String getResponsePayload(HttpServletResponse response) {
ContentCachingResponseWrapper wrapper = WebUtils.getNativeResponse(response, ContentCachingResponseWrapper.class);
if (wrapper != null) {
byte[] buf = wrapper.getContentAsByteArray();
if (buf.length > 0) {
int length = Math.min(buf.length, 5120);
try {
return new String(buf, 0, length, wrapper.getCharacterEncoding());
}
catch (UnsupportedEncodingException e) {
logger.error(e.getMessage(), e);
}
}
}
return "[unknown]";
}
private void updateResponse(HttpServletResponse response) throws IOException {
ContentCachingResponseWrapper responseWrapper =
WebUtils.getNativeResponse(response, ContentCachingResponseWrapper.class);
responseWrapper.copyBodyToResponse();
}
}
当 multipart = true 时,它在 updateResponse(response) 部分失败。我尝试发送不同的响应,我什至可以发送空响应,但它只是没有正确处理它,并且当这是多部分时,类不会继续到控制器。
更新:
如果我删除记录器类,那么请求会直接发送到控制器,并且它可以完美运行。
这是 Bean 的初始化方式:
import com.altair.autoTester.logs.LoggableDispatcherServlet;
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.DispatcherServlet;
@Configuration
public class LogsConfig {
@Bean
public ServletRegistrationBean dispatcherRegistration() {
return new ServletRegistrationBean(dispatcherServlet());
}
@Bean(name = DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
public DispatcherServlet dispatcherServlet() {
return new LoggableDispatcherServlet();
}
【问题讨论】:
标签: java spring-boot http servlets