撒哈拉的故事
在web项目中,引入Struts2jar包
Eclipse Version: Neon Release (4.6.0)
Structs2jar包版本:2.3.31
下载地址:http://download.youkuaiyun.com/detail/peng_hong_fu/9676455
原始 struts.xml 和 web.xml 文件
struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
</package>
</struts>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>structs-timer</display-name>
<!-- 配置Struts2-->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
拦截器实例1-action中加入拦截器
一个计算Action执行的时间的实例
流程:
index.jsp —> TimerAction.java(action) —> TimerInterceptor.java —> success.jsp
index.jsp请求一个action,action执行的同时,引用拦截器,最后返回success.jsp
1 index.jsp页面
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
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>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
</head>
<body>
<a href="timer">访问Action并计算执行Action花费的时间</a>
</body>
</html>
2 TimerAction.java –Action
响应 index.jsp 的action 请求。
TimerAction.java
//package com.peng.action;
import com.opensymphony.xwork2.ActionSupport;
public class TimerAction extends ActionSupport {
@Override
public String execute() throws Exception {
for (int i = 0; i < 10000; i++) {
System.out.println("I Love IMOOC!");
}//耗时操作
return SUCCESS;
}
}
在 struts.xml 文件中配置 action
struts.xml
..
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
<action name="timer" class="com.peng.action.TimerAction">
<result>/success.jsp</result>
</action>
</package>
</struts>
3 TimerInterceptor.java–拦截器
TimerInterceptor.java
//package com.peng.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
/**
* Title: TimerInterceptor
* Description: 计算执行Action花费的时间
* @author Peng
* @date 下午3:32:45
*/
public class TimerInterceptor extends AbstractInterceptor {
//自动调用此方法
@Override
public String intercept(ActionInvocation invocation) throws Exception {
//1.执行Action之前
long start = System.currentTimeMillis();
//2.执行下一个拦截器,如果已经是最后一个拦截器,则执行目标action
String result = invocation.invoke();
//3.执行Action之后
long end = System.currentTimeMillis();
System.out.println("执行Action花费的时间:"+(end-start)+"ms");
return result;
}
}
在structs.xml文件中配置 拦截器
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
<!-- 注册拦截器 -->
<interceptors>
<interceptor name="mytimer"
class="com.peng.interceptor.TimerInterceptor"></interceptor>
</interceptors>
<action name="timer"
class="com.peng.action.TimerAction">
<result>/success.jsp</result>
<!-- 为Action显式引用拦截器后,默认的拦截器defaultStack不再生效,需要手工引用 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
<!-- 引用拦截器 -->
<interceptor-ref name="mytimer"></interceptor-ref>
</action>
</package>
</struts>
4 success.jsp 结果页
success.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
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>
<base href="<%=basePath%>">
<title>My JSP 'success.jsp' page</title>
</head>
<body>
访问Action成功!
</body>
</html>
执行结果
I Love IMOOC!
I Love IMOOC!
I Love IMOOC!
I Love IMOOC!
I Love IMOOC!
I Love IMOOC!
I Love IMOOC!
I Love IMOOC!
I Love IMOOC!
执行Action花费的时间:601ms
内建拦截器
在引入包 struts2-core-2.3.31.jar中的structs-default.xml文件中有关于默认内建拦截器的配置
拦截器实例2-权限验证拦截器
用户登录过后,通过action–auto可以跳转到后台管理页面manager.jsp(位于WEB-INFO目录下),若没有登录则跳转到login.jsp登录界面。
主要是通过,对 action –auto进行拦截,判断条件。
配置structs2
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>struts2-authInterceptor</display-name>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
起始的struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<!-- 动态方法调用,用来配置action后缀名之类的-->
<constant name="struts.devMode" value="true" />
<!-- struts的开发模式,默认值为false,改为true就是以后一旦就改这个文件中的配置就不用去重启tomcat-->
<package name="default" namespace="/" extends="struts-default">
</package>
</struts>
1 index.jsp起始页面
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
这里是index.jsp页面
</body>
</html>
2 manager.jsp后台管理页面
位于WEB-INF的page目录下
manager.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
后台管理页面,只有已登录的用户才能访问
</body>
</html>
3 login.jsp登录界面
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>用户登录</h2>
${loginError}
<form action="login.action" method="post">
用户名:<input type="text" name="username"/></br>
密码:<input type="password" name="password"/></br>
<input type="submit" value="登录"/>
</form>
</body>
</html>
4 LoginAction.java 配置Action
LoginAction.java
//package com.peng.action;
import java.util.Map;
import org.apache.struts2.interceptor.SessionAware;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction extends ActionSupport implements SessionAware {
private String username;
private String password;
private Map<String,Object> session;
public void setSession(Map<String,Object> session){
this.session = session;
}
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 String login(){
if("admin".equals(username)&&"123".equals(password)){
session.put("loginInfo", username);
return SUCCESS;
}else{
session.put("loginError", "用户名或密码不正确");
return ERROR;
}
}
}
配置LoginAction
..
<action name="login" class="com.peng.action.LoginAction"
method="login">
<result>/WEB-INF/page/manager.jsp</result>
<result name="error">/login.jsp</result>
</action>
..
4 AuthInterceptor.java配置拦截器
AuthInterceptor.java
//package com.peng.interceptor;
import java.util.Map;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class AuthInterceptor extends AbstractInterceptor {
@Override
public String intercept(ActionInvocation invocation) throws Exception {
ActionContext context = ActionContext.getContext();
Map<String,Object> session = context.getSession();
if(session.get("loginInfo")!=null){
String result = invocation.invoke();
return result;
}else{
return "login";
}
}
}
配置AuthInterceptor
..
<interceptors >
<interceptor name="auth" class="com.peng.interceptor.AuthInterceptor"></interceptor>
<!-- 自定义拦截器栈myStack,组合了defaultStack和auth -->
<interceptor-stack name="myStack">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="auth"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 通过此Action访问后台管理页面,需要判断用户是否已登录,如果登录,则跳转到登录页面-->
<action name="auth">
<result>/WEB-INF/page/manager.jsp</result>
<result name="login">/login.jsp</result>
<!-- 引用自定义的拦截器栈 -->
<interceptor-ref name="myStack"></interceptor-ref>
</action>
..
5 struts.xml
struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
<interceptors >
<interceptor name="auth" class="com.peng.interceptor.AuthInterceptor"></interceptor>
<!-- 自定义拦截器栈myStack,组合了defaultStack和auth -->
<interceptor-stack name="myStack">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="auth"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 通过此Action访问后台管理页面,需要判断用户是否已登录,如果登录,则跳转到登录页面-->
<action name="auth">
<result>/WEB-INF/page/manager.jsp</result>
<result name="login">/login.jsp</result>
<!-- 引用自定义的拦截器栈 -->
<interceptor-ref name="myStack"></interceptor-ref>
</action>
<action name="login" class="com.peng.action.LoginAction"
method="login">
<result>/WEB-INF/page/manager.jsp</result>
<result name="error">/login.jsp</result>
</action>
</package>
</struts>
6 程序结果
1.第一次输入action–auth进入的是登录界面,而不是后台管理页面
此时执行的是下面的逻辑,拦截器执行,判断登录信息为空,返回“login”
..
<action name="auth">
<result>/WEB-INF/page/manager.jsp</result>
<result name="login">/login.jsp</result>
<!-- 引用自定义的拦截器栈 -->
<interceptor-ref name="myStack"></interceptor-ref>
</action>
..
..
if(session.get("loginInfo")!=null){
String result = invocation.invoke();
return result;
}else{
return "login";
}
..
2.此时在登录页面login.jsp,只输入用户名admin
由于下面的判断语句,返回的是ERROE
..
if("admin".equals(username)&&"123".equals(password)){
session.put("loginInfo", username);
return SUCCESS;
}else{
session.put("loginError", "用户名或密码不正确");
return ERROR;
}
..
3.正确输入用户名和密码:admin和123,进入到后台管理页面
网站的后缀名为 login.action
4.此时,输入网址:http://localhost:8080/struts2-authInterceptor/auth
可以跳转到后台管理页面,而不是和第一次登录时,跳转到login页面
源码
拦截器实例1-action中加入拦截器:http://download.youkuaiyun.com/detail/peng_hong_fu/9676738
拦截器实例2-权限验证拦截器:http://pan.baidu.com/s/1pLCmlzd