Struts 2 拦截器响应 Header 未设置

Struts 2 Interceptor Response Header Not Being Set

Struts 2.5.18

我在 Struts 2 拦截器中设置 header 时遇到问题,客户端没有收到 header 返回。我在另一个 Struts 2 项目中使用完全相同的拦截器没有问题。

我确实偶然发现了这个 post ,它有同样的问题,并通过从 ServletActionContext.getResponse() 获取响应切换到从调用上下文 [=15= 获取响应来解决它]

结果与 header 相同,但仍未发送回浏览器。我正在使用开发人员工具来监视响应 header 但它不存在。

此外,我在响应中调用 setHeader() 后立即放入调试消息,以查看响应是否包含使用 containsHeader() 的新 header。 containsHeader() 导致 FALSE,就好像 setHeader 根本不工作一样。

有人对响应 object 可能发生的情况有任何建议吗? intercept() 方法如下

public String intercept(ActionInvocation invocation) throws Exception {
    String result = invocation.invoke();
    Boolean hasValidationErrors = Boolean.FALSE;
    Object action = invocation.getAction();
    if(action instanceof ValidationAware) {
        ValidationAware validationAware = (ValidationAware) action;
        hasValidationErrors = validationAware.hasErrors();

    }

    HttpServletResponse response = (HttpServletResponse) invocation.getInvocationContext().get(StrutsStatics.HTTP_RESPONSE);
    response.setHeader(VALIDATION_FLAG_HEADER_NAME, String.valueOf(hasValidationErrors));

    if (log.isDebugEnabled()) log.debug("Does response contain new header? " + response.containsHeader(VALIDATION_FLAG_HEADER_NAME));

    return result;
}

更新:应用 Dave 的修复后的工作代码

  public String intercept(ActionInvocation invocation) throws Exception {

        invocation.addPreResultListener((actionInvocation, resultCode) -> {
            // perform operation necessary before Result execution
            Boolean hasValidationErrors = Boolean.FALSE;
            Object action = invocation.getAction();
            if(action instanceof ValidationAware) {
                ValidationAware validationAware = (ValidationAware) action;
                hasValidationErrors = validationAware.hasErrors();

            }

            HttpServletResponse response = (HttpServletResponse) invocation.getInvocationContext().get(StrutsStatics.HTTP_RESPONSE);
            response.setHeader(VALIDATION_FLAG_HEADER_NAME, String.valueOf(hasValidationErrors));

            if (log.isDebugEnabled()) log.debug("Does response contain new header? " + response.containsHeader(VALIDATION_FLAG_HEADER_NAME));

        });

        return invocation.invoke();
    }

您在调用 invoke 后设置 header,此时已呈现响应。

来自https://struts.apache.org/core-developers/writing-interceptors.html

Keep in mind that invoke will return after the result has been called (eg. after you JSP has been rendered), making it perfect for things like open-session-in-view patterns. If you want to do something before the result gets called, you should implement a PreResultListener.

在调用 invoke 之前设置 header,或者实施 PreResultListener