当前位置: 首页 > 知识库问答 >
问题:

用ContentCachingResponseWrapper提取主体的Spring过滤器总是返回200

容鸿畴
2023-03-14

下面是我的过滤器:

@Component
public class CustomHttpTraceFilter extends OncePerRequestFilter {

    private ContentTrace contentTrace;
    private final ContentTraceEvents contentTraceEvents;

    public CustomHttpTraceFilter(ContentTraceEvents contentTraceEvents) {
        this.contentTraceEvents = contentTraceEvents;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request);
        ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response);
        contentTrace = new ContentTrace();
        contentTrace.setTimestamp(LocalDateTime.now());

        try {
            filterChain.doFilter(requestWrapper, responseWrapper);
        } finally {
            afterRequest(requestWrapper, responseWrapper);
        }

    }

    private void afterRequest(ContentCachingRequestWrapper requestWrapper, ContentCachingResponseWrapper responseWrapper) throws IOException {

        /*
         *  From Request Headers
         */

        String method = requestWrapper.getMethod();
        boolean isGetMethod = method.equals("GET");
        // At the moment get requests are not being tracked
        if (isGetMethod) {
            responseWrapper.copyBodyToResponse();
            return;
        }

        contentTrace.setTimeTaken(System.currentTimeMillis() - contentTrace.timestamp.atZone(ZoneId.systemDefault()).toEpochSecond());
        contentTrace.setMethod(method);
        contentTrace.setRemoteAddress(requestWrapper.getRemoteAddr());
        contentTrace.setUri(requestWrapper.getRequestURI());

        contentTrace.setHost(requestWrapper.getHeader("host"));
        contentTrace.setAuthorization(requestWrapper.getHeader("authorization"));
        contentTrace.setUserAgent(requestWrapper.getHeader("user-agent"));
        contentTrace.setReferer(requestWrapper.getHeader("referer"));

        contentTrace.setReqBody(getRequestPayload(requestWrapper));

        /*
         *  From Response Headers
         */

        contentTrace.setStatus(responseWrapper.getStatusCode());

        contentTrace.setResBody(getResponsePayload(responseWrapper));

        /*
         * Important to copy the original response body, because it is removed.
         */

        responseWrapper.copyBodyToResponse();

        // publish event
        contentTraceEvents.publishContentTrace(contentTrace);
    }


    private String getRequestPayload(HttpServletRequest request) {
        ContentCachingRequestWrapper wrapper =
                WebUtils.getNativeRequest(request, ContentCachingRequestWrapper.class);
        if (wrapper != null) {
            byte[] buf = wrapper.getContentAsByteArray();
            if (buf.length > 0) {
                int length = buf.length;
                try {
                    return new String(buf, 0, length, wrapper.getCharacterEncoding());
                } catch (UnsupportedEncodingException ex) {
                    return "[unknown]";
                }
            }
        }
        return "";
    }

    private String getResponsePayload(ContentCachingResponseWrapper wrappedResponse) {
        try {
            if (wrappedResponse.getContentSize() <= 0) {
                return null;
            }
            return new String(wrappedResponse.getContentAsByteArray(), 0,
                    wrappedResponse.getContentSize(),
                    wrappedResponse.getCharacterEncoding());
        } catch (UnsupportedEncodingException e) {
            logger.error(
                    "Could not read cached response body: " + e.getMessage());
            return null;
        }
    }
}

共有1个答案

沈飞跃
2023-03-14

我在使用OncePerRequestFilter时也遇到了同样的问题。

响应体仅带有关于成功响应(200)的数据。

对于错误响应状态(400,500),响应正文为空。

public enum DispatcherType {
    FORWARD,
    INCLUDE,
    REQUEST,
    ASYNC,
    ERROR;

    private DispatcherType() {
    }
}
registrationBean.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
 类似资料:
  • 提取过滤器用于过滤数据源中提取的数据。如果用户从数据源中提取数据,则使用此过滤器。 将文本文件连接到Tableau后,可以在数据源选项卡的右上角看到两个选项“实时(Live)”和“提取(Extract)”。 实时连接直接连接到数据源。提取连接从数据源中提取数据,并在Tableau存储库中创建本地副本。下面逐步给出创建提取过滤器的过程。 第1步:使用Tableau连接文本文件。 单击“提取(Extr

  • 问题内容: 我想在 angularjs 1.2中 使用unsafe-html 。没有html的过滤器可以工作,而html则不能。我做的事: 我在我的html头中添加了angular-sanitize: 我的角度模块: 我的HTML: 编辑:更新为 问题答案: 已在Angular 1.2中删除。由于您正确地清理了输入内容,因此应该使用。 示例:http://plnkr.co/edit/0bHeXra

  • 我正在做一个简单的项目,它使用Spring Boot 2和使用Kotlin的Spring WebFlux。我为我的处理函数编写了测试(在测试中,我使用Mockito模拟依赖项)。 然而,我的路由函数似乎不会触发处理程序,因为我的所有请求都返回HTTP 404 not FOUND(即使路由是正确的)。 我已经查看了各种其他项目,以了解这些测试应该如何编写(这里,这里),但问题仍然存在。 代码如下(也

  • 我试图在我的kotlin应用程序中实现基于Spring security JWT的授权,但是在每次/authenticate(登录)时,UsernamePasswordAuthenticationToken在数据库中找到用户,但返回403:用户凭据已经过期,即使是刚刚添加的用户。 SecurityConfiguration类: AuthorizationFilter类

  • 为了解决这一限制, 从发布AEM实例启动的工作流:当从AEM发布实例提交自适应表单、交互式通信或信件时,所有工作流实例都使用服务用户创建。在这些情况下,工作流实例数据中不会捕获登录用户的用户名。 我添加了一个过滤器servlet来拦截AEM Forms servlet之前的初始表单提交,使用请求包装器修改请求正文,添加原始用户ID。 我审查了以下资源: 如何在java过滤器中更改servlet请求

  • 我在Spring遇到了身份验证问题。我有身份验证筛选器扩展UsernamePasswordAuthenticationFilter。 实现UserDetailsService 和SecurityConfig类 如果我尝试让邮递员发送具有良好凭据的身份验证请求,在调试器模式下一切正常(AuthFilter和UserDetailsService),但服务器返回401并且Authfilter中的成功身份