SSH学习-Struts2中的session

Struts中也有session,跟其他框架类似,也需要用它保存用户信息,或者其他信息。学习发现,Struts2获取session有三种方式,下面引入登录的案例,分别使用三种方式验证用户名和密码信息。

Struts2获取session的三种方式

(1)使用工厂方法获取,使用ActionContext实现,session为Map<String,Object>类型

(2)使用注入方式获取session,session为Map<String,Object>类型

(3)使用ServletActionContext实现session,session为HttpSession

具体实现方式

(1)使用工厂方法获取

struts.xml中配置,其中首先进入登录页面,提交登录时,需要修改form表单的地址为/loginWithSession/loginWithFactorySession.action

<!--登录,使用session对登录信息进行验证  -->
  <package name="loginWithSession" namespace="/loginWithSession" extends="struts-default">
    <!-- 进入登录页面 -->
    <action name="toLogin">
      <result>
        /WEB-INF/loginWithSession.jsp
      </result>
    </action> 
    <!-- 登录验证,使用工厂方法获取session -->  
    <action name="loginWithFactorySession" class="com.boe.Filter.LoginWithSessionByFactory">
      <result name="success">
        /WEB-INF/ok.jsp
      </result>
      <result name="error">
        /WEB-INF/loginWithSession.jsp
      </result>    
    </action>
  </package>

对应loginWithSession.jsp的内容:

<%@page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Session验证-登录</title>
</head>
<body style="font-family:'微软雅黑';font-size:20px;">
    <!-- 使用JSTL标签 -->
    <!-- 标签的作用主要用来产生字符串类型的-->
    <!-- 另外还有一个问题,如果在注释里写了c标签,不加引号,编译会提示标签未结束 -->
    <c:url var="url" value="/loginWithSession/loginWithFactorySession.action"></c:url>
    <form action="${url}" method="post"><!-- 使用url标签,路径会默认在前面加上项目名,否则action里写路径就需要加上项目名 -->
       <div>
         <!-- 登录不成功,返回提示信息 -->
         <h1>${message}</h1>
       </div>
       <div>
         <label>用户名:</label>
         <input type="text" name="user.username" /><!-- 使用域模型传递数据,需要写完成实体类.属性名 -->
       </div>
       <div>
         <label>密码:</label>
         <input type="password" name="user.password" />
       </div>
       <div>
         <input type="submit" value="登录" />
       </div>
    </form>
</body>
</html>
View Code

对应ok.jsp的内容:

<%@page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>获取登录后结果</title>
</head>
<body style="font-family:'微软雅黑';font-size:20px;">
     <h1>Hello Struts2</h1>
     <!-- 使用EL表达式从服务端获取数据 -->
     <h2>"Hello!" ${LoginSuccess},采用session验证</h2><!-- 直接使用session中的key -->
</body>
</html>
View Code

控制器LoginWithSessionByFactory中写法:

package com.boe.Filter;

import java.util.Map;

import com.boe.Entity.User;
import com.opensymphony.xwork2.ActionContext;

public class LoginWithSessionByFactory {
    //属性
    private User user;
    private String message;
    
    //使用工厂方法获取session
    ActionContext ctx=ActionContext.getContext();
    Map<String,Object> session=ctx.getSession();
    
    //session的get方法    
    public Map<String, Object> getSession() {
        return session;
    }

    //user和message的get set方法
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    
    //默认execute方法
    public String execute() {
        System.out.println(user);
        //登录验证
        if(user.getUsername().equals("clyang")&&user.getPassword().equals("123")) {
            session.put("LoginSuccess", user.getUsername());
            return "success";
        }
        else {
            message="用户名或密码错误,请重新登录!";
            return "error";                    
        }
    }        
    
}
View Code

 测试结果:

第一次登录密码12,是错误的密码,因此提示用户名和密码错误,第二次密码123正确,因此进入ok.jsp页面,并显示登录后用户名为clyang,说明session被工厂方法获取,并成功用于保存用户信息。

(2)使用注入的方式获取session

struts.xml中配置,跟上面类似,其中进入登录页面部分不需要修改,需要改动的是增加一个action,里面控制器使用注入的session,并且修改loginWithSession.jsp中action地址:

<!-- 登录验证,使用注入获取session -->
...其他省略,参考第一个配置,添加一个action即可

    <action name="login" class="com.boe.Filter.LoginWithSession">
      <result name="success">
        /WEB-INF/ok.jsp
      </result>
      <result name="error">
        /WEB-INF/loginWithSession.jsp
      </result>
    </action> 

修改loginWithSession.jsp中action地址:

<%@page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Session验证-登录</title>
</head>
<body style="font-family:'微软雅黑';font-size:20px;">
    <!-- 使用JSTL标签 -->
    <!-- 标签的作用主要用来产生字符串类型的-->
    <!-- 另外还有一个问题,如果在注释里写了c标签,不加引号,编译会提示标签未结束 -->
    <c:url var="url" value="/loginWithSession/login.action"></c:url>
    <form action="${url}" method="post"><!-- 使用url标签,路径会默认在前面加上项目名,否则action里写路径就需要加上项目名 -->
       <div>
         <!-- 登录不成功,返回提示信息 -->
         <h1>${message}</h1>
       </div>
       <div>
         <label>用户名:</label>
         <input type="text" name="user.username" /><!-- 使用域模型传递数据,需要写完成实体类.属性名 -->
       </div>
       <div>
         <label>密码:</label>
         <input type="password" name="user.password" />
       </div>
       <div>
         <input type="submit" value="登录" />
       </div>
    </form>
</body>
</html>
View Code

添加控制器LoginWithSession,其中实现类需要实现SessionAware接口,并需要实现接口方法setSession,但是后面统一get set方法设置后刚好有它,因此可以先不管报错提示实现未实现的方法,有get set方法后自然报错消失。

package com.boe.Filter;
/**
 * session验证用户信息
 * @author yangchaolin
 */

import java.util.Map;

import org.apache.struts2.interceptor.SessionAware;

import com.boe.Entity.User;

public class LoginWithSession implements SessionAware{
    
    //属性
    private User user;
    private Map<String,Object> session;
    private String message;
    
    //添加get set方法    
    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Map<String, Object> getSession() {
        return session;
    }

    //以下是get set得到的,也是SeesionAware接口方法
    public void setSession(Map<String, Object> session) {
                this.session=session;
    }
    
    //默认execute方法
    public String execute() {
        System.out.println(user);
        //登录验证
        if(user.getUsername().equals("clyang")&&user.getPassword().equals("123")) {
            session.put("LoginSuccess", user.getUsername());
            return "success";
        }
        else {
            message="用户名或密码错误,请重新登录!";
            return "error";                    
        }
    }
   
}
View Code

测试结果:

第一次登录密码12,是错误的密码,因此提示用户名和密码错误,第二次密码123正确,因此进入ok.jsp页面,并显示登录后用户名为clyang,说明session注入成功,并成功用于保存用户信息。

 (3)使用ServletActionContext获取session

这种方法获取的session跟前面两种类型不一样,前者为Map,后者为HttpSession。因此控制器中不能使用put方法,需要改成相应的setAttribute方法。

struts.xml中的配置,添加一个action,专门对应最后一种方式,并修改loginWithSession.jsp的action地址,跟配置文件中一致。

<!-- 登录验证,使用ServletActionContext获取session -->
    <action name="loginWithSessionByServlet" class="com.boe.Filter.LoginWithSessionByServlet">
      <result name="success">
        /WEB-INF/ok.jsp
      </result>
      <result name="error">
        /WEB-INF/loginWithSession.jsp
      </result>     
    </action>

修改loginWithSession.jsp中action地址:

<%@page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Session验证-登录</title>
</head>
<body style="font-family:'微软雅黑';font-size:20px;">
    <!-- 使用JSTL标签 -->
    <!-- 标签的作用主要用来产生字符串类型的-->
    <!-- 另外还有一个问题,如果在注释里写了c标签,不加引号,编译会提示标签未结束 -->
    <c:url var="url" value="/loginWithSession/loginWithSessionByServlet.action"></c:url>
    <form action="${url}" method="post"><!-- 使用url标签,路径会默认在前面加上项目名,否则action里写路径就需要加上项目名 -->
       <div>
         <!-- 登录不成功,返回提示信息 -->
         <h1>${message}</h1>
       </div>
       <div>
         <label>用户名:</label>
         <input type="text" name="user.username" /><!-- 使用域模型传递数据,需要写完成实体类.属性名 -->
       </div>
       <div>
         <label>密码:</label>
         <input type="password" name="user.password" />
       </div>
       <div>
         <input type="submit" value="登录" />
       </div>
    </form>
</body>
</html>
View Code

添加控制器LoginWithSessionByServlet,其中注意session的类型是HttpSession。

package com.boe.Filter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.struts2.ServletActionContext;

import com.boe.Entity.User;

public class LoginWithSessionByServlet {
    //属性
    private User user;
    private String message;
    
    //使用ServletActionContext获取session
    HttpServletRequest req=ServletActionContext.getRequest();
    HttpSession session=req.getSession();
    
    //session的get方法    
    public HttpSession getSession() {
        return session;
    }

    //user和message的get set方法
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    
    //默认execute方法
    public String execute() {
        System.out.println(user);
        //登录验证
        if(user.getUsername().equals("clyang")&&user.getPassword().equals("123")) {
            session.setAttribute("LoginSuccess", user.getUsername());
            return "success";
        }
        else {
            message="用户名或密码错误,请重新登录!";
            return "error";                    
        }
    }        
    
}
View Code

测试结果:

第一次登录密码12,是错误的密码,因此提示用户名和密码错误,第二次密码123正确,因此进入ok.jsp页面,并显示登录后用户名为clyang,说明HttpSession类型的session成功生成,并成功用于保存用户信息。

结论

以上三种方式都可以获取session,完成业务目标,其中ActionContext和ServletActionContext是主动获取,另外一种是被动注入。另外除了ServletActionContext获取的session是HttpSession类型,其他两种都是Map<String,Object>。

参考博文:

https://www.cnblogs.com/chong518/p/5243143.html

原文地址:https://www.cnblogs.com/youngchaolin/p/10806372.html