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根本不起作用一样。
有人对响应对象可能发生的情况有任何建议吗?
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();
}
答案 0 :(得分:1)
您要在调用invoke
后设置标题,此时响应已呈现。
来自https://struts.apache.org/core-developers/writing-interceptors.html:
请记住,调用将在结果被调用后返回(例如,在呈现JSP之后),从而使其非常适合于诸如视图中打开会话模式之类的事情。如果要在调用结果之前做点什么,则应实现
PreResultListener
。
在调用invoke
或实现PreResultListener
之前设置标题。