login.jsp <% ... @ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <% ... @ taglib prefix="s" uri="/struts-tags" %> <% ... String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; %> <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" > < html > < head > < s:head /> < base href ="<%=basePath%>" > < title > My JSP 'login.jsp' starting page </ title > < meta http-equiv ="pragma" content ="no-cache" > < meta http-equiv ="cache-control" content ="no-cache" > < meta http-equiv ="expires" content ="0" > < meta http-equiv ="keywords" content ="keyword1,keyword2,keyword3" > < meta http-equiv ="description" content ="This is my page" > <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </ head > < body > < div style ="color:red" > < s:fielderror /> </ div > < s:form action ="login" theme ="simple" > < table align ="center" width ="60%" > < tr > < td align ="right" > Name: </ td > < td > < s:textfield name ="name" /> </ td > < td > < s:submit value ="Submit" /> </ td > </ tr > < tr > < td align ="right" colspan ="3" > < a href ="welcome.action" > Go to welcome page directly. </ a > </ td > </ tr > </ table > </ s:form > </ body > </ html > welcome.jsp <% ... @ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <% ... @ taglib prefix="s" uri="/struts-tags" %> <% ... String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; %> <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" > < html > < head > < s:head /> < base href ="<%=basePath%>" > < title > My JSP 'login.jsp' starting page </ title > < meta http-equiv ="pragma" content ="no-cache" > < meta http-equiv ="cache-control" content ="no-cache" > < meta http-equiv ="expires" content ="0" > < meta http-equiv ="keywords" content ="keyword1,keyword2,keyword3" > < meta http-equiv ="description" content ="This is my page" > <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </ head > < body > < s:form action ="logout" theme ="simple" > < h2 > Welcome! </ h2 > < table align ="center" width ="60%" > < tr > < td > Name: </ td > < td > < s:property value ="#session['USER_INFO'].name" /> </ td > </ tr > < tr > < td > Login Time: </ td > < td > < s:property value ="#session['USER_INFO'].loginTime" /> </ td > </ tr > < tr > < td > < s:submit value ="Logout" /> </ td > < td > < a href ="login.action" > Back to login. </ a > </ td > </ tr > </ table > </ s:form > </ body > </ html > struts.xml <! DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd" > < struts > < include file ="struts-default.xml" /> <!-- 定义含“权限检查拦截器”的包,供其他模块引用 --> < package name ="struts-default-with-auth-check" extends ="struts-default" > < interceptors > <!-- 定义“权限检查拦截器” --> < interceptor name ="authCheck" class ="interceptor.AuthCheckInterceptor" > </ interceptor > <!-- 定义含“权限检查拦截器”的拦截器栈,注意缺省的拦截器栈“defaultStack”要放在前面 --> < interceptor-stack name ="myStack" > < interceptor-ref name ="defaultStack" /> < interceptor-ref name ="authCheck" ></ interceptor-ref > </ interceptor-stack > </ interceptors > <!-- 正式应用可能含很多package,为了能从其他package中跳转到登录页面,把登录页面定义成全局result --> < default-interceptor-ref name ="myStack" ></ default-interceptor-ref > < global-results > < result name ="globalLogin" > login.jsp </ result > </ global-results > </ package > <!-- >>>>>>>>>>>>>>>>>>>>>> p1模块 <<<<<<<<<<<<<<<<<<<<<<<<<<<< --> <!-- 注意package的extends属性,系统中只有“登录/注销”操作不需要检查权限 --> < package name ="p1" extends ="struts-default" > <!-- 登录 --> < action name ="login" class ="action.LoginAction" > < result > welcome.jsp </ result > < result name ="input" > login.jsp </ result > </ action > <!-- 注销 --> < action name ="logout" class ="action.LogoutAction" > < result > login.jsp </ result > </ action > </ package > <!-- >>>>>>>>>>>>>>>>>>>>>> p2模块 <<<<<<<<<<<<<<<<<<<<<<<<<<<< --> < package name ="p2" extends ="struts-default-with-auth-check" > <!-- 试图未经过登录,直接访问welcome页面,测试用 --> < action name ="welcome" class ="action.WelcomeAction" > < result > welcome.jsp </ result > </ action > </ package > </ struts > LoginAction.java package action; import java.util.Date; import java.util.Map; import bean.LoginedUser; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport;@ SuppressWarnings ( " unchecked " ) public class LoginAction extends ActionSupport ... { private String name; private static final long serialVersionUID = -2907891170345505600L; @ Override public String execute() throws Exception ...{ Map session = ActionContext.getContext().getSession(); LoginedUser user = new LoginedUser(); user.setName(name); user.setLoginTime(new Date()); if (name.startsWith("U_")) ...{//假设用户名以"U_"开头才是合法的 session.put("USER_INFO", user);//只有此处会向session里面加入key=“USER_INFO”的对象 return SUCCESS; } else ...{ addFieldError("name", "name is invalid."); return INPUT; } } public void validate() ...{ if (null == name || name.trim().length() < 1) ...{ addFieldError("name", "name is required."); } } public String getName() ...{ return name; } public void setName(String name) ...{ this.name = name; }} LogoutAction.java package action; import java.util.Map; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport;@ SuppressWarnings ( " unchecked " ) public class LogoutAction extends ActionSupport ... { private static final long serialVersionUID = -2907891170345505600L; @ Override public String execute() throws Exception ...{ Map session = ActionContext.getContext().getSession(); if (null != session.get("USER_INFO")) ...{// 刪除session中key="USER_INFO"的對象 session.remove("USER_INFO"); } return SUCCESS;//注销完毕,回到登录页面 }} WelcomeAction.java package action; import com.opensymphony.xwork2.ActionSupport;@ SuppressWarnings ( " unchecked " ) public class WelcomeAction extends ActionSupport ... { private static final long serialVersionUID = -2907891170345505600L; @ Override public String execute() throws Exception ...{ return SUCCESS; }} AuthCheckInterceptor.java package interceptor; import java.util.Map; import bean.LoginedUser; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor;@ SuppressWarnings ( " unchecked " ) public class AuthCheckInterceptor extends AbstractInterceptor ... { private static final long serialVersionUID = -4535462154177128320L; @ Override public String intercept(ActionInvocation ai) throws Exception ...{ Map session = ActionContext.getContext().getSession(); LoginedUser user = (LoginedUser)session.get("USER_INFO"); if(null==user)...{// 判断session里是否有key="USER_INFO"的对象 return "globalLogin";// 转发到登录页面 } return ai.invoke(); }}