将LogClientInfo修改为全阶段过滤器以支持将请求的响应代码和响应体存入AccessLog表

This commit is contained in:
2025-09-26 11:54:14 +08:00
parent 2c0b79e7d9
commit f6eb9ebb51
@@ -1,13 +1,12 @@
package xyz.thewhitedog9487.WebAPI.Controller.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.ContentCachingResponseWrapper;
import xyz.thewhitedog9487.WebAPI.Data.Entity.AccessLog;
import xyz.thewhitedog9487.WebAPI.Data.Repository.AccessLogRepository;
@@ -18,52 +17,65 @@ import java.util.Locale;
@Slf4j
@Component
public class LogClientInfo extends OncePerRequestFilter {
public class LogClientInfo implements Filter {
@Autowired AccessLogRepository AccessLogRepository;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
log.info("接收到对于{} {} 的请求", request.getMethod(), request.getRequestURL() + ( ( request.getQueryString() == null ) ? "" : "?" + request.getQueryString() ) );
if ( request.getHeader("CF-Connecting-IP".toLowerCase() ) instanceof String IP ) {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest HttpServletRequest = (HttpServletRequest) request;
HttpServletResponse HttpServletResponse = (HttpServletResponse) response;
var Response = new ContentCachingResponseWrapper(HttpServletResponse);
log.info("接收到对于{} {} 的请求", HttpServletRequest.getMethod(), HttpServletRequest.getRequestURL() + ( ( HttpServletRequest.getQueryString() == null ) ? "" : "?" + HttpServletRequest.getQueryString() ) );
if ( HttpServletRequest.getHeader("CF-Connecting-IP".toLowerCase() ) instanceof String IP ) {
/*
↑ 如果成功完成instanceof模式匹配,那么模式变量一定非空
相当于是:
if ( request.getHeader("CF-Connecting-IP".toLowerCase() ) != null ) {
String IP = request.getHeader( "CF-Connecting-IP".toLowerCase() ); }
if ( HttpServletRequest.getHeader("CF-Connecting-IP".toLowerCase() ) != null ) {
String IP = HttpServletRequest.getHeader( "CF-Connecting-IP".toLowerCase() ); }
*/
log.info("请求携带了CF-Connecting-IP头部,IP{}", IP); }
else if( request.getHeader("X-Forwarded-For".toLowerCase() ) instanceof String IP ) {
else if( HttpServletRequest.getHeader("X-Forwarded-For".toLowerCase() ) instanceof String IP ) {
IP = IP.split(",")[0].trim();
log.info("请求携带了X-Forwarded-For头部,IP{}", IP); }
else {
log.info("请求未携带CF-Connecting-IP和X-Forwarded-For头部,HttpServletRequest获取到的IP为:{}", request.getRemoteAddr()); }
if ( request.getHeader("CF-IPCountry".toLowerCase() ) instanceof String IP ) {
log.info("请求未携带CF-Connecting-IP和X-Forwarded-For头部,HttpServletRequest获取到的IP为:{}", HttpServletRequest.getRemoteAddr()); }
if ( HttpServletRequest.getHeader("CF-IPCountry".toLowerCase() ) instanceof String IP ) {
var Country = Locale.of(Locale.PRC.getLanguage(), IP, Locale.SIMPLIFIED_CHINESE.getVariant());
log.info("请求携带了CF-IPCountry头部,ISO3166代码:{},对应的国家/地区:{}", IP, Country.getDisplayCountry(Locale.SIMPLIFIED_CHINESE)); }
else {
log.info("请求未携带CF-IPCountry头部,无法获取国家/地区信息。"); }
var UserAgent = request.getHeader("User-Agent");
var UserAgent = HttpServletRequest.getHeader("User-Agent");
if( UserAgent == null ){
log.info("请求未携带User-Agent头部,无法获取客户端软件信息。"); }
else{
log.info("请求的User-Agent{}", UserAgent); }
var Log = new AccessLog(
null,
request.getRequestId(),
request.getHeader("CF-Connecting-IP".toLowerCase() ),
request.getHeader("X-Forwarded-For".toLowerCase() ),
request.getRemoteAddr(),
request.getHeader("CF-IPCountry".toLowerCase() ),
( request.getHeader("CF-IPCountry".toLowerCase() ) == null ) ? null : Locale.of(Locale.PRC.getLanguage(), request.getHeader("CF-IPCountry".toLowerCase() ), Locale.SIMPLIFIED_CHINESE.getVariant()).getISO3Country(),
HttpServletRequest.getRequestId(),
HttpServletRequest.getHeader("CF-Connecting-IP".toLowerCase() ),
HttpServletRequest.getHeader("X-Forwarded-For".toLowerCase() ),
HttpServletRequest.getRemoteAddr(),
HttpServletRequest.getHeader("CF-IPCountry".toLowerCase() ),
( HttpServletRequest.getHeader("CF-IPCountry".toLowerCase() ) == null ) ? null : Locale.of(Locale.PRC.getLanguage(), HttpServletRequest.getHeader("CF-IPCountry".toLowerCase() ), Locale.SIMPLIFIED_CHINESE.getVariant()).getISO3Country(),
UserAgent,
request.getMethod(),
request.getRequestURL().toString(),
request.getQueryString(),
Collections.list( request.getHeaderNames() )
HttpServletRequest.getMethod(),
HttpServletRequest.getScheme(),
HttpServletRequest.getProtocol(),
HttpServletRequest.getRequestURL().toString(),
HttpServletRequest.getQueryString(),
Collections.list( HttpServletRequest.getHeaderNames() )
.stream()
.map( name -> name + ": " + Collections.list(request.getHeaders(name)) )
.map( name -> name + ": " + Collections.list(HttpServletRequest.getHeaders(name)) )
.reduce( ( a, b ) -> a + "\n" + b )
.orElse(""),
Instant.now() );
Instant.now(),
null,
null );
Log = AccessLogRepository.save(Log);
chain.doFilter(request, Response);
var ResponseBody = new String( Response.getContentAsByteArray(), Response.getCharacterEncoding() );
Log.setResponseStatusCode(HttpServletResponse.getStatus());
Log.setResponseBody(ResponseBody);
AccessLogRepository.save(Log);
filterChain.doFilter(request, response); } }
log.info("请求处理完成,响应状态码:{}", HttpServletResponse.getStatus());
Response.copyBodyToResponse(); } }