【学习笔记】Struts2--04

1.拦截器介绍及自定义拦截器

拦截器,拦截器链(连接器栈)

拦截器的实现原理:大部分的拦截器方法都是通过代理的方式来调用的。

struts2的拦截器实现:当请求到达struts2的ServletDispatcher时,struts2会查找配置文件,并根据其配置实例化相应的拦截器对象,然后串成一个列表,最后一个一个地调用列表中的拦截器。

架构图:

(1)拦截器的创建

创建方式1:实现Interceptor接口

package cn.itcast.a_interceptor;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;

//拦截器:第一种创建方式
//拦截器生命周期:随项目的启动而创建,随项目关闭而销毁
public class MyInterceptor implements Interceptor {
	@Override
	//初始化方法
	public void init() {
		
	}

	@Override
	//拦截方法
	public String intercept(ActionInvocation arg0) throws Exception {
		return null;
	}

	
	@Override
	//销毁方法
	public void destroy() {
		
	}
}

创建方式2:继承AbstractInterceptor

package cn.itcast.a_interceptor;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

//创建方式2: 继承AbstractInterceptor -> struts2的体贴
//帮我们空实现了init 和 destory方法. 我们如果不需要实现这两个方法,就可以只实现intercept方法
public class MyInterceptor2 extends AbstractInterceptor {

	@Override
	public String intercept(ActionInvocation arg0) throws Exception {
		
		return null;
	}

}

创建方式3:继承MethodFilterInterceptor(常用)

package cn.itcast.a_interceptor;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;

//继承:MethodFilterInterceptor 方法过滤拦截器
//功能: 定制拦截器拦截的方法.
//	定制哪些方法需要拦截.
//	定制哪些方法不需要拦截
public class MyInterceptor3 extends MethodFilterInterceptor{

	@Override
	protected String doIntercept(ActionInvocation invocation) throws Exception {
		//前处理
		System.out.println("MyInterceptor3 的前处理!");
		//放行
		String result = invocation.invoke();
		//后处理
		System.out.println("MyInterceptor3 的后处理!");
		
		return result;
	}

}

(2)拦截器API

拦截器放行、放行前后的业务操作、不放行:

package cn.itcast.a_interceptor;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;

//继承:MethodFilterInterceptor 方法过滤拦截器
//功能: 定制拦截器拦截的方法.
//	定制哪些方法需要拦截.
//	定制哪些方法不需要拦截
public class MyInterceptor3 extends MethodFilterInterceptor{

	@Override
	protected String doIntercept(ActionInvocation invocation) throws Exception {
		//放行前的处理
		System.out.println("MyInterceptor3 的前处理!");
		//放行
		String result = invocation.invoke();
		//放行后的处理
		System.out.println("MyInterceptor3 的后处理!");
		
		return result;//如果return “success”,就是不放行,即不执行后续的拦截器以及Action,直接交给Result处理结果.进行页面跳转
	}

}

2.拦截器的配置

三步:注册拦截器-->配置拦截器栈-->指定包中默认拦截器栈

还可通过拦截器定制需要拦截的方法

<?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>
	<package name="inter" namespace="/" extends="struts-default" >
	<interceptors>
	<!-- 1.注册拦截器 -->
		<interceptor name="myInter3" class="cn.itcast.a_interceptor.MyInterceptor3"></interceptor>
	<!-- 2.注册拦截器栈 -->
		<interceptor-stack name="myStack">
			<!-- 自定义拦截器引入(建议放在20个拦截器之前) -->
			<interceptor-ref name="myInter3">
				<!-- 指定哪些方法不拦截
				 <param name="excludeMethods">add,delete</param> -->
				 <!-- 指定哪些方法需要拦截 -->
				 <param name="includeMethods">add,delete</param>
			</interceptor-ref>
			<!-- 引用默认的拦截器栈(20个) -->
			<interceptor-ref name="defaultStack"></interceptor-ref>
		</interceptor-stack>	
	</interceptors>
	<!-- 3.指定整个包中的默认拦截器栈 -->
		<default-interceptor-ref name="myStack"></default-interceptor-ref>
		
		
		<action name="Demo1Action_*" class="cn.itcast.a_interceptor.Demo1Action" method="{1}" >
			<!-- 如果需要让某个action走特定拦截器,可为Action单独指定走哪个拦截器(栈) 
			<interceptor-ref name="myStack"></interceptor-ref>-->
			<result name="success" type="dispatcher" >/index.jsp</result>
		</action>
	</package>
	<package name="tag" namespace="/" extends="struts-default" >
		<action name="Demo2Action" class="cn.itcast.b_tag.Demo2Action" method="execute" >
			<result name="success" type="dispatcher" >/tag1.jsp</result>
		</action>
		<action name="Demo3Action" class="cn.itcast.b_tag.Demo3Action" method="execute" >
			<result name="success" type="dispatcher" >/tag2.jsp</result>
		</action>
	</package>
</struts>

案例:

客户管理系统中,自定义一个拦截器,拦截除登录之外的所有请求,若访问的页面没有登录,就跳转到登录页

部分代码和配置:(全局结果集,error处理)

//service层
if(existU==null) {
			throw new RuntimeException("用户名不存在");
		}
		if(!existU.getPassword().equals(user.getPassword())) {
			throw new RuntimeException("密码错误");
		}
package cn.itheima.web.interceptor;

import java.util.Map;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;

public class LoginInterceptor extends MethodFilterInterceptor {
	//自定义一个拦截器,指定不拦截登陆方法. 其他方法都拦截
	
	@Override
	protected String doIntercept(ActionInvocation invocation) throws Exception {
		
		//1.获得session
		Map<String, Object> session = ActionContext.getContext().getSession();
		//2.获得登陆标识
		Object object = session.get("user");
		//3.判断登陆标识是否存在
		if(object == null){
			//不存在=>没登录=>重定向到登录页面
			return "toLogin";
		}else{
			//存在=>已经登陆=>放行
			return invocation.invoke();
		}
		
	}

}
<?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>
	<!-- 指定struts2是否以开发模式运行
			1.热加载主配置.(不需要重启即可生效)
			2.提供更多错误信息输出,方便开发时的调试
	 -->
	<constant name="struts.devMode" value="true"></constant>
	<package name="crm" namespace="/" extends="struts-default" >
		<interceptors>
			<!-- 注册拦截器 -->
			<interceptor name="loginInterceptor" class="cn.itheima.web.interceptor.LoginInterceptor"></interceptor>
			<!-- 注册拦截器栈 -->
			<interceptor-stack name="myStack">
				<interceptor-ref name="loginInterceptor">
					<param name="excludeMethods">login</param>
				</interceptor-ref>
				<interceptor-ref name="defaultStack"></interceptor-ref>
			</interceptor-stack>
		</interceptors>
		<!-- 指定包中的默认拦截器栈 -->
		<default-interceptor-ref name="myStack"></default-interceptor-ref>
		<!-- 定义全局结果集(访问某个action,若没有登录,就return “toLogin”,因为不知道访问的是哪个action,所以不能在action中配置toLogin,所以此处需要配置全局结果集) -->
		<global-results>
			<result name="toLogin" type="redirect" >/login.jsp</result>
		</global-results>
		<global-exception-mappings>
			<!-- 如果出现java.lang.RuntimeException异常,就将跳转到名为error的结果(error需要在相应的action中配置) -->
			<exception-mapping result="error" exception="java.lang.RuntimeException"></exception-mapping>
		</global-exception-mappings>
		
	
		<action name="CustomerAction_*" class="cn.itheima.web.action.CustomerAction" method="{1}" >
			<result name="list" >/jsp/customer/list.jsp</result>
			<result name="toList" type="redirectAction">
	             <param name="actionName">CustomerAction_list</param>
	             <param name="namespace">/</param>
	         </result>
		</action>
		<action name="UserAction_*" class="cn.itheima.web.action.UserAction" method="{1}" >
			<result name="toHome" type="redirect" >/index.htm</result>
             <!--登录信息错误,会返回error-->
			<result name="error"  >/login.jsp</result>
		</action>
	</package>
</struts>

3.Struts2标签库(了解)

标签体系:

Struts2标签库结构:

代码示例1(jsp页面需要引入struts标签库):普通标签

package cn.itcast.b_tag;

import java.util.ArrayList;
import java.util.List;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

public class Demo2Action extends ActionSupport {
	

	public String execute() throws Exception {
		
		List<String> list = new ArrayList<>();
		list.add("tom");
		list.add("jerry");
		list.add("jack");
		list.add("rose");
		list.add("hqy");
		
		ActionContext.getContext().put("list", list);
		return SUCCESS;
	}

	
	
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
   <%@ taglib prefix="s" uri="/struts-tags" %>
<!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>
<!-- 遍历标签 iterator -->
<!--不写var,list会放在栈顶,<s:property />默认从栈顶取数据 ------------------------------------- -->
<s:iterator value="#list" >
	<s:property /><br>
</s:iterator>
<!-- ------------------------------------- --><hr>
<s:iterator value="#list" var="name" >
	<s:property value="#name" /><br>
</s:iterator>
<!-- 数数------------------------------------- --><hr>
<s:iterator begin="1" end="100" step="1"  >
	<s:property />|
</s:iterator>
<!-- ------------------if else elseif------------------- --><hr>

<s:if test="#list.size()==4">
	list长度为4!
</s:if>
<s:elseif test="#list.size()==3">
	list长度为3!
</s:elseif>
<s:else>
	list不3不4!
</s:else>

<!-- ------------------property 配合ognl表达式页面取值 ------------------- --><hr>

<s:property value="#list.size()" />
<s:property value="#session.user.name" />

</body>
</html>

示例2:UI标签

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
   <%@ taglib prefix="s" uri="/struts-tags" %>
<!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>
	<!-- struts2表单标签 -->
	<!-- 好处1: 内置了一套样式.  -->
	<!-- 好处2: 自动回显,根据栈中的属性  -->
	<!-- theme:指定表单的主题
			xhtml:默认
			simple:没有主题
	 -->
	<s:form action="Demo3Action" namespace="/" theme="xhtml" >
		<s:textfield name="name" label="用户名"  ></s:textfield>
		<s:password name="password" label="密码" ></s:password>
		<s:radio list="{'男','女'}" name="gender" label="性别" ></s:radio>
		<s:radio list="#{1:'男',0:'女'}" name="gender" label="性别" ></s:radio>
		<s:checkboxlist list="#{2:'抽烟',1:'喝酒',0:'烫头'}" name="habits" label="爱好" ></s:checkboxlist>
		<s:select list="#{2:'大专',1:'本科',0:'硕士'}" headerKey="" headerValue="---请选择---" name="edu" label="学历" >
		</s:select>
		<s:file name="photo" label="近照" ></s:file>
		<s:textarea name="desc" label="个人简介" ></s:textarea>
		<s:submit value="提交" ></s:submit>
	</s:form>
	
<!-- 取出错误信息(在action的方法中this.addActionError("这里出错了")) -->
	<s:actionerror/>
</body>
</html>

 

转载于:https://my.oschina.net/u/3943244/blog/2205039

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值