我正在尝试在spring boot中使用spring @Controller
记录我的@Aspect
请求(请求名称和数据)。
问题是当使用没有有效数据的@Valid
时,该方法不会执行,因为参数解析发生在之前。
我也尝试过以下解决方案,但它们对我没有用处:
@InitBinder
,但它仍然让我遇到第一个问题而且不是很干净的解决方案。如果有人对如何在@Valid中使用@Aspect有其他想法或好建议,那将非常有帮助。 谢谢
答案 0 :(得分:2)
我能够使用以下代码实现目标。
@ControllerAdvice
@Component
public class ControllerLogger {
@InitBinder
private void initBinder(WebDataBinder binder,WebRequest webRequest) {
//log the request and data here .
}
}
答案 1 :(得分:2)
要记录请求和响应标头和正文,您可以注册日志过滤器:
package demo;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.apache.commons.io.output.TeeOutputStream;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mock.web.DelegatingServletOutputStream;
@Configuration
public class HttpServerConfig {
private final static Logger LOG = Logger.getLogger(HttpServerConfig.class.getName());
@Bean
public FilterRegistrationBean logFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setDispatcherTypes(DispatcherType.REQUEST);
registration.setFilter(new Filter() {
@Override
public void init(FilterConfig fc) throws ServletException {
LOG.info("Init LOG Request Filter");
}
private void logRequest(HttpServletRequest httpReq) throws IOException {
// log request headers
LOG.info("### Request Headers:");
for (String header : Collections.list(httpReq.getHeaderNames())) {
LOG.log(Level.INFO, "\t* {0}: {1}", new Object[]{header, httpReq.getHeader(header)});
}
// log request body
Scanner qs = new Scanner(httpReq.getInputStream()).useDelimiter("\\A");
String qb = qs.hasNext() ? qs.next() : "[empty body]";
LOG.log(Level.INFO, "### Request body: `{0}` ###", qb);
}
private void logResponse(HttpServletResponse httpResp, ByteArrayOutputStream baos) {
// log response headers
LOG.log(Level.INFO, "### Response [{0}] Headers:", httpResp.getStatus());
for (String header : httpResp.getHeaderNames()) {
LOG.log(Level.INFO, "\t* {0}: {1}", new Object[]{header, httpResp.getHeader(header)});
}
// log response body
LOG.log(Level.INFO, "### Response body: `{0}` ###", baos.toString());
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
logRequest((HttpServletRequest) req);
HttpServletResponse httpResp = (HttpServletResponse) resp;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
final PrintStream ps = new PrintStream(baos);
chain.doFilter(req, new HttpServletResponseWrapper(httpResp) {
@Override
public ServletOutputStream getOutputStream() throws IOException {
return new DelegatingServletOutputStream(new TeeOutputStream(super.getOutputStream(), ps));
}
@Override
public PrintWriter getWriter() throws IOException {
return new PrintWriter(new DelegatingServletOutputStream(new TeeOutputStream(super.getOutputStream(), ps)));
}
});
logResponse(httpResp, baos);
}
@Override
public void destroy() {
LOG.info("Destroy LOG Request Filter");
}
});
return registration;
}
}