【问题标题】:Struts 2 Interceptor Response Header Not Being Set未设置 Struts 2 拦截器响应标头
【发布时间】:2019-03-13 14:51:43
【问题描述】:

Struts 2.5.18

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

我确实偶然发现了这篇 How can I configure HTTP Response Headers in a Struts2 Interceptor? 的帖子,它有同样的问题,并通过从 ServletActionContext.getResponse() 获取响应切换到从调用上下文 invocation.getInvocationContext().get(StrutsStatics.HTTP_RESPONSE) 获取它来解决它

这最终导致标题仍然没有被发送回浏览器的相同结果。我正在使用开发者工具监控响应头,但它不存在。

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

是否有人对响应对象可能发生的事情有任何建议?下面是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's Fix 后的工作代码

  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();
    }

【问题讨论】:

    标签: java struts2 struts2-interceptors


    【解决方案1】:

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

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

    请记住,invoke 将在调用结果后返回(例如,在您呈现 JSP 之后),使其非常适合诸如 open-session-in-view 模式之类的事情。如果你想在结果被调用之前做一些事情,你应该实现一个PreResultListener

    在调用invoke 之前设置标头,或者实现PreResultListener

    【讨论】:

    • 感谢戴夫,这确实解决了问题。这一直在使用的项目使用 Rest 插件,因此它必须与允许它在那里运行的 rest 插件有所不同。感谢您的帮助
    • 对于任何将来查看此内容的人的快速更新:我认为工作流(拦截器)会使拦截器堆栈短路,因此在验证和工作流之后定义此拦截器会导致拦截器不触发。我继续将此拦截器移到堆栈顶部并注册 PreResultListener。我已经用有效的拦截器代码更新了帖子。
    猜你喜欢
    • 2013-06-18
    • 2018-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多