问题的由来:
在网页设计中,当一个用户退出登录时,往往要去除Session中的登录信息,然后返回之前引用页。在Action中,删除登录信息,很简单就可以做到。但是如何使result指向引用页呢?
尝试 :
1、return的 Action.INPUT:( 失败 )
报错是 找不到 名为Input的result配置。
2、在result的配置中使用OGNL表达式:( 失败 )
<result type="redirect">${#request.header['referer']}</result>
控制台会有警告,大意是 无法解析表达式#request.header['referer']。
其实,仔细想来(也测试过)。在Struts2的 OGNL context中的 request、session等,仅仅包含 key-value的内容。和Servlet规范中的request、session等不一样。
3、在Action中,直接获取HTTPServletRequest,然后配置result转向。( 成功 )
LogoutAction中有个属性:
//................
private String preURL;
public String getPreURL() {
return preURL;
}
//.................
然后在Action的某个方法(比如execute)中,操作HTTPServletRequest,改变preURL的值。
//..........
HttpServletRequest request = ServletActionContext.getRequest();
String contextPath = request.getContextPath();
String preURL = request.getHeader("referer");
int begin = preURL.indexOf(contextPath);
preURL = preURL.substring(begin + contextPath.length());
//..........
最后,配置result:
<result type="redirect">${preURL}</result>
不足之处:
需要在每一个要求获得引用页的Action中加入相同的代码,解决方式不够优雅 ⊙﹏⊙。
最终解决:借助于Struts2提供的Interceptor来优雅地解决问题。
1、一个interface -- PreURLAware
package edu.xjtu.jxg.struts.aware;
/**
* Actions that want access to the Where the request is come from should implement this interface.<p />
*
* This interface uses the HTTPServletQuest.getHeader("referer") to achieve this goal.<p/>
*/
public interface PreURLAware {
public void setPreURL(String preURL);
}
2、一个Interceptor -- PreURLInterceptor
package edu.xjtu.jxg.interceptor;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import edu.xjtu.jxg.struts.aware.PreURLAware;
public class PreURLInterceptor extends AbstractInterceptor {
private static final long serialVersionUID = 5421682585093337518L;
@Override
public String intercept(ActionInvocation invocation) throws Exception {
Object obj = invocation.getAction();
if (obj instanceof PreURLAware) {
HttpServletRequest request = ServletActionContext.getRequest();
String contextPath = request.getContextPath();
String preURL = request.getHeader("referer");
if (preURL == null)
((PreURLAware) obj).setPreURL(null);
else {
int begin = preURL.indexOf(contextPath);
preURL = preURL.substring(begin + contextPath.length());
((PreURLAware) obj).setPreURL(preURL);
}
}
return invocation.invoke();
}
}
3、修改需要获得引用页的Action
需要获得引用页(preURL)的Action实现 PreURLAware接口
4、修改result的配置,即加入PreURLInterceptor
定义Interceptor:
<interceptors> <interceptor name="preURL" class="edu.xjtu.jxg.interceptor.PreURLInterceptor"></interceptor> </interceptors>
引用Interceptor:
<action name="logout" class="edu.xjtu.jxg.struts.action.LogoutAction"> <interceptor-ref name="preURL"></interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> <result type="redirect">${preURL}</result> </action>
大功告成!!O(∩_∩)O