【发布时间】:2020-03-06 01:01:52
【问题描述】:
我有 Spring Boot,我需要在 DB 中记录用户操作,所以我写了 HandlerInterceptor:
@Component
public class LogInterceptor implements HandlerInterceptor {
@Autovired
private LogUserActionService logUserActionService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws IOException {
String userName = SecurityContextHolder.getContext().getAuthentication().getName();
String url = request.getRequestURI();
String queryString = request.getQueryString() != null ? request.getQueryString() : "";
String body = "POST".equalsIgnoreCase(request.getMethod()) ? new BufferedReader(new InputStreamReader(request.getInputStream())).lines().collect(Collectors.joining(System.lineSeparator())) : queryString;
logUserActionService.logUserAction(userName, url, body);
return true;
}
}
但是根据这个答案Get RequestBody and ResponseBody at HandlerInterceptor“RequestBody 只能读取一次”,所以据我所知,我读取了输入流,然后 Spring 尝试做同样的事情,但是流已经被读取并且我收到了一个错误: “缺少所需的请求正文...”
所以我尝试了不同的方法来制作缓冲输入流,即:
HttpServletRequest httpServletRequest = new ContentCachingRequestWrapper(request);
new BufferedReader(new InputStreamReader(httpServletRequest.getInputStream())).lines().collect(Collectors.joining(System.lineSeparator()))
或者
InputStream bufferedInputStream = new BufferedInputStream(request.getInputStream());
但没有任何帮助 我也尝试使用
@ControllerAdvice
public class UserActionRequestBodyAdviceAdapter extends RequestBodyAdviceAdapter {
但它只有正文,没有 URL 或请求参数等请求信息 也尝试使用过滤器,但结果相同。
所以我需要一种从请求中获取信息的好方法,例如用户、URL、参数、正文(如果存在)并将其写入数据库。
【问题讨论】:
-
请使用过滤器检查这个,它对我有用。 gist.github.com/int128/e47217bebdb4c402b2ffa7cc199307ba
-
Harshit,您的示例中没有正文阅读,只有 URL 等。
-
是的,检查
logRequestBody方法。 -
Harshit,你确定这段代码有效吗?因为我根据您的示例发送了 JSON 正文并编写了下一个代码: new ContentCachingRequestWrapper(request).getContentAsByteArray();它返回空字节数组,但我的控制器按预期得到了我的 DTO 实体。所以我有正文,但方法 getContentAsByteArray 什么也没返回。
标签: java spring spring-boot spring-mvc