在LoginActon.java有代码:import java.util.Map;import org.apache.struts2.interceptor.SessionAware;import ch06.dao.IUserDAO;
import ch06.dao.UserDAOHibernateImpl;
import ch06.struts2.Interceptor.AuthenticationInterceptor;import com.opensymphony.xwork2.ActionSupport;public class LoginAction extends ActionSupport implements SessionAware { private static final long serialVersionUID = 1L;

private String username;
    private String password;
private String message;
    IUserDAO userDAO = new UserDAOHibernateImpl();
    private Map sessionMap;
    
    public String execute() throws Exception {
     if(isInvalid(username,password)){
     sessionMap.put(AuthenticationInterceptor.USER_SESSION_KEY, "user");
     message ="你好, "+ username;
     //显示成功页面
         return SUCCESS;
     }else{
     //将出错信息加入到ActionError
     message = "输入错误的用户名和密码!请重新输入!";
     //返回到输入页面
     return INPUT;
     }
    }struts.xml中有:        <action name="Login" class="ch06.struts2.LoginAction">
            <result name="input">index.jsp</result>
            <result name="success">success.jsp</result>
        </action>问题:为什么在index.jsp中的<s:property value="message">能够显示LoginActon中的message属性,在success.jsp同样存在这个疑惑,上面的return SUCCESS;和return INPUT;是否等于return "success",return "input";写成那样有什么好?自定义验证拦截器
import java.util.Map;import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
public class AuthenticationInterceptor implements Interceptor  {  private static final long serialVersionUID = 1L;

 public static final String USER_SESSION_KEY = "UserSessionKey";
 
 public void destroy() {}  public void init() {}
     public String intercept(ActionInvocation actionInvocation) throws Exception {
 //取得Session
         Map session = actionInvocation.getInvocationContext().getSession();
 //从Session里获得登录时保存进session的User类
         String user = (String) session.get(USER_SESSION_KEY);
         //判断用户名是否为空  
         boolean isAuthenticated = (null!=user);
         if (!isAuthenticated) {//如果未通过登录验证
            return Action.LOGIN;   //返回登录页面     
          
         }else{       
        
         return actionInvocation.invoke();//返回验证通过  
        
         }
     }
}问题:上面的自定义拦截器的String user = (String) session.get(USER_SESSION_KEY);为什么能获得LoginAction.java中Map类型的属性,还有public String intercept(ActionInvocation actionInvocation) throws Exception中的actionInvocation是什么来的,它是哪里传递过来的? 对于return Action.LOGIN,return actionInvocation.invoke()有同第一个问题的疑惑。

解决方案 »

  1.   

    1.<s:property>标签就是jsp的自定标签而已,在自定义标签的java代码中取值栈的变量。
    2.SUCCESS这些不就是常量嘛,如果没记错的话应该是在ActionSupport中定义的。
    3.肯定中间还有一步session.set(USER_SESSION_KEY, xxx),绝对不是直接在AuthenticationInterceptor里读到了LoginAction的私有成员sessionMap。另外,怎么没看见在LoginAction里sessionMap是在哪儿被初始化的?
    4.Interceptor本身是被Struts2框架自动调用的,所以actionInvocation当然也是由框架传来的。
    5.去理解一下Interceptor的执行时序吧,Interceptor本身是非纯责任链模式,actionInvocation.invoke()相当于击鼓传花的下一站。
      

  2.   

    去看下 struts的convention。return "success"是convention的写法。而return SUCCESS是com.opensymphony.xwork2.Aciton 里面定义的常量
    源码里面是这样写的
      public static final String SUCCESS = "success";
    所以说他们相等基本上是对的。至于拦截器还得想楼主学习,一只想研究,不知道如何下手。
      

  3.   

    回答1中的“取值栈的变量”不明白,请说通俗点吧
    回答3中session.set(USER_SESSION_KEY, xxx),我没有在代码中找到,还是不明白自定义拦截器的怎么能获得LoginAction.java中Map类型的属性。
      

  4.   

    没想明白拦载器有撒难学的。你首先应该去理解拦截器的执行时序,
    基本是这样的
    I1 begin
    I2 begin
    I3 begin
    MyAction Method
    I3 end
    I2 end
    I1 end
    I的begin和end其实就是在intercept()方法中actionInvocation.invoke()的前部分和后部分。
    而Servlet Filter是这样的
    F1 filter
    F2 filter
    F3 filter
    MyAction Method
    看出区别了吧。剩下的去记住Struts2的拦截器种类,以及默认配置中的调用顺序。
    最后挑几个常见的拦截器看看源代码,背背API,完事。
      

  5.   


    1.看一下org.apache.struts2.components.Property源代码,仔细读读start()方法。如果读不懂多半是对ognl不了解,补补ognl的valueStack知识。这部分确实不是三言两语说得清的。
    3.LoginAction你没贴完所以我也不知道在哪初始化的。
      

  6.   

    我晕,重要的东西看漏了,你的LoginAction不是实现了SessionAware接口么,
    你把LoginAction.setSession()方法贴来看看。
      

  7.   

    下面是LoginAction.javar的代码,大家帮忙说是在哪里初始化的package ch06.struts2;import java.util.Map;import org.apache.struts2.interceptor.SessionAware;import ch06.dao.IUserDAO;
    import ch06.dao.UserDAOHibernateImpl;
    import ch06.struts2.Interceptor.AuthenticationInterceptor;import com.opensymphony.xwork2.ActionSupport;public class LoginAction extends ActionSupport implements SessionAware { private static final long serialVersionUID = 1L;

    private String username;
        private String password;
    private String message;
        IUserDAO userDAO = new UserDAOHibernateImpl();
        private Map sessionMap;
        
        public String execute() throws Exception {
         if(isInvalid(username,password)){
         sessionMap.put(AuthenticationInterceptor.USER_SESSION_KEY, "user");
         message ="你好, "+ username;
         //显示成功页面
             return SUCCESS;
         }else{
         //将出错信息加入到ActionError
         message = "输入错误的用户名和密码!请重新输入!";
         //返回到输入页面
         return INPUT;
         }
        }    private boolean isInvalid(String userName,String password) {      
         return userDAO.isValidUser(username, password);
        }   
        public String getUsername() {
            return username;
        }
        
        public void setUsername(String username) {
            this.username = username;
        }    public String getPassword() {
            return password;
        }    public void setPassword(String password) {
            this.password = password;
        } public Map getSessionMap() {
    return sessionMap;
    } public void setSessionMap(Map sessionMap) {
    this.sessionMap = sessionMap;
    } public void setSession(Map map) {
     this.sessionMap = map;
    } public String getMessage() {
    return message;
    } public void setMessage(String message) {
    this.message = message;
    }}
      

  8.   

    在setSession()就对sessionMap做了初始化嘛。Struts2自动调用setSession(Map sessionMap),并且这个入参的map就是actionInvocation.getInvocationContext().getSession(),所以不管是get还是set都是在同一个map进行的。
      

  9.   

    谢谢yagumo!
    我基本上明白了,我还有一事想请请教你的:在哪些书能找到比较全面的讲到像的说的那些内容,我只有一本《JAVA EE》的项目书,我想找本或几本好点的关于Spring,hibernate,struts的书!
      

  10.   

    呵呵,我学这些都没有专门去买书,像struts2学习基本就是官方文档和走读源代码。xxxstruts/spring in action系列书名声比较大。