struts2-总结篇

第一节

struts2框架应用在javaee三层中web层框架,是轻量级框架
struts2在struts1和webwork基础之上发展全新的框架
之前web阶段提交表单时候到servlet里面,现在开始不写servlet,使用struts2实现之前servlet的功能

struts2框架版本
(1)hibernate5.x
(2)struts2.3.24

解压文件之后,有目录结构

2 常见web层框架

1 struts1
2 webwork
3 springMVC(常用)

3.web层框架特点

  1. 只要框架是应用在web层框架,这类框架共同特点:有前端控制器(过滤器)
  2. 2 画图分析struts2解决问题:

在这里插入图片描述

4.Struts2框架入门案例

第一步 导入jar包
(1)到apps里面找到示例程序war包,使用压缩文件把war包打开,从示例程序里面复制struts2需要jar包

第二步 创建action


/**
 * action类
 * @author asus
 *
 */
public class HelloAction {
	/*
	 * serlvet
	 * (1) 继承HttpServlet,重写方法
	 * (2) 在web.xml配置servlet,访问servlet路径
	 * (3)访问servlet时候,servlet里面service方法执行
* action
	 * (1)action需要类似于servlet进行配置,配置访问路径
	 * (2)访问action时候,action里面方法默认执行 名称固定的 execute方法
	 * */
	/*
	 * action里面的方法不能有参数
	 * action的方法可以没有返回值 void,如果有返回值,必须是String
	 */
	public String execute() {
		return "ok";
	}
}

第三步 配置action访问路径
(1)之前配置servlet,在web.xml中进行配置
在这里插入图片描述
(2)配置action不是在web.xml配置,创建struts2核心配置文件完成action配置
(3)struts2核心配置文件名称和位置固定的

  • 位置在src下面
    - 名称是固定 struts.xml
    在这里插入图片描述
    (4)引入dtd约束,到示例程序里面复制dtd约束
    在这里插入图片描述
    (5)配置action访问路径
<package name="demo" extends="struts-default" namespace="/">
		<action name="hello" class="cn.itcast.action.HelloAction">
			<result name="ok">/hello.jsp</result>
		</action>
	</package>

(6)访问action路径:http://localhost:8080/struts2_day01/hello

在这里插入图片描述
**(7)**上面代码访问之后,出现404问题,因为在struts2框架里面需要过滤器,所以需要配置struts2过滤器,是struts2提供的过滤器

在web.xml文件中

<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>

效果:
访问action路径,跳转到页面中

在这里插入图片描述

4.Struts2开发流程分析

●struts2执行过程
在这里插入图片描述
● 配置没有提示
1 可以上网
2 把dtd约束配置到eclipse中
在这里插入图片描述

Struts2流程:
(1)是过滤器
(2)过滤器在服务器启动时候创建,过滤器创建执行init方法
做事情是 加载配置文件,加载配置文件分成两部分:
第一部分 自己创建配置文件
第二部分 struts2自带配置文件
在这里插入图片描述
(1)有加载顺序
Struts2自带配置文件
default.properties: 常量设置
struts-defaul.xml: struts2拦截器
struts-plugin.xml: 插件

(1)加载配置文件中,主要关心自己可以修改配置文件
struts.xml: 配置action路径
struts.properties: 配置常量
web.xml

5.Struts2的核心配置文件

1 struts2核心配置文件名称和位置固定

(1)位置在src下面,名称是struts.xml

2 有很多标签,每个标签里面有属性

(1)package标签
(2)action标签
(3)result标签

6.标签package

1 在配置文件中配置action访问路径,要求必须package标签
2 类似于代码中包
3 在一个配置文件中可以写多个package标签,name属性值不能相同的
4 extends属性:
(1)在extends里面写struts-default之后,配置action有struts2封装的功能
(2)因为struts2里面封装很多功能,在拦截器里面封装,使用struts2拦截器

5 namespace属性:
(1)namespace属性值和action标签name属性值构成访问地址
在这里插入图片描述
6 两个细节问题
(1)package里面extends写其他package的name属性值
在这里插入图片描述
(2)namespace值修改,访问路径写法
在这里插入图片描述

6.标签action

1 action标签写在package标签里面
2 action的name属性
(1)name属性值和package标签namespace属性值构成访问路径
3 action的class属性
(1)action类全路径
4 action的method属性
(1)配置action不是execute的方法执行
5 在一个package里面可以写多个action标签,name值不能相同

7.标签result

1 result标签写在action标签里面
2 result标签作用:根据action方法返回值,配置到不同的路径里面
3 result标签有name属性:和action方法返回值一样
4 result标签有type属性:如何到路径中(转发或者重定向)
(1)默认值做转发操作
5 在action标签可以有多个result标签,name值不能一样

8. Struts2常量配置

1 使用struts2是框架,在框架里面封装很多功能,
这些功能中其中一部分功能在常量封装的

2 struts2默认的常量位置(记住)
在这里插入图片描述

3 修改struts2默认常量值
有三种方式
(1)常用的方式
在struts.xml中进行常量配置
在这里插入图片描述
(2)第二种方式
在src下面创建名称是struts.properties

(3)第三种方式
在web.xml进行常量配置
在这里插入图片描述
4 加载顺序

在这里插入图片描述
(1)如果在三个配置文件中都修改同一个常量,最终以最后一次加载文件修改值为准

- 介绍最常用常量
(1)之前提交表单到servlet里面,现在提交表单到action里面,
提交中文数据,在servlet获取乱码问题,
解决:post设置编码方式,get做编码转换
(2)action获取post提交中文数据,乱码问题不需要自己解决,帮处理。
如果get提交还是有乱码的,自己处理](https://img-blog.csdnimg.cn/20201224195842738.png)
在这里插入图片描述
(1)访问action路径,添加扩展名称,可以添加.action,可以什么都不添加
(2)建议添加.action
在这里插入图片描述
(2)如果设置值true之后,修改struts.xml配置文件不需要重启动服务器

8.分模块开发配置

1 一般开发中,每个人自己写自己struts2配置文件,最终把每个配置文件引入到核心配置文件中

在这里插入图片描述

9.Action编写方式
1 action编写有三种方式
第一种 创建普通类,不继承任何类,不实现任何接口 pojo
在这里插入图片描述
第二种 创建类,让实现接口Action

在这里插入图片描述
(1)Action接口里面有常量
在这里插入图片描述
就是字符串success
在这里插入图片描述
如果在action方法有返回值,必须在result标签里面进行配置,如果不配置出现404问题,
在这里插入图片描述
但是如果返回值NONE,不需要在result标签配置
在这里插入图片描述
在这里插入图片描述
(1)字符串login
在这里插入图片描述
(1)错误页面配置
在这里插入图片描述
(1)比如在表单里面输入值 abc,在action使用int类型接收abc,返回input

第三种 创建类,继承类ActionSupport(建议)
在这里插入图片描述

10.访问action的方法

在这里插入图片描述
有三种方式实现
第一种 使用action标签method属性,在这个属性里面写执行的action的方法
第二种 使用通配符方式实现
第三种 动态访问实现(不用)

11. 使用method属性

<!-- 配置action的方法访问 -->
	<package name="" extends="struts-default" namespace="/">
		<!-- 第一种方式配置action的方法访问 -->
		<!-- 执行add方法 
			method:执行action方法名称
		-->
		<action name="ordersAdd" class="cn.itcast.method.OrdersAction" method="add"></action>
		
		<!-- 执行update方法 -->
		<action name="ordersUpdate" class="cn.itcast.method.OrdersAction" method="update"></action>
	</package>

1 方式有缺陷:action里面每个方法都需要配置action,如果有很多的方法,配置很多action

●使用通配符实现
使用通配符方式时候,需要在action标签name属性里面使用符号 *
(1)* 可以匹配任意内容
(2)比如ordersadd,使用可以匹配到
比如ordersupdate,使用
可以匹配到

<!-- 使用通配符方式配置 -->
	<package name="demo" extends="struts-default" namespace="/">
		<!-- 
			在action标签name属性里面添加* 
			orders_执行的方法名称
			(1)orders_add,使用orders_*可以匹配到,*相当于办成 add
			    orders_update,使用orders_*可以匹配到,*相当于变成 update
			(2)add和update是方法名称
			(3)method里面写* 值
			(4)获取*(5)访问地址里面添加执行方法名称
			
			*_* 获取第一个*{1},获取第二个*{2}
		 -->
		<action name="orders_*" class="cn.itcast.method.OrdersAction" method="{1}"></action>
	</package>

2 访问action的方法还有一种方式是:
动态访问,实际开发一般不用,作为了解
在这里插入图片描述
(1)开启常量
在这里插入图片描述
(2)配置action,不需要method属性
在这里插入图片描述
(3)访问时候,写action的name属性值后面添加感叹号 ! ,后面添加执行方法名称

12.案例-客户列表

1 修改超链接路径
在这里插入图片描述

2 创建action
public class CustomerAction extends ActionSupport {

	//列表的方法
	public String list() {
		
		return "list";
	}
}

3 配置action
	<package name="demo" extends="struts-default" namespace="/">
		<action name="customer_*" class="cn.itcast.action.CustomerAction" method="{1}">
			<result name="list">/jsp/customer/list.jsp</result>
		</action>
	</package>

4 配置过滤器
     <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>

5 action实现
	//列表的方法
	public String list() {
		/**
		 * 作业:
		 * 查询数据库返回客户列表的list集合
		 * 使用hibernate实现
		 * (1)创建实体类
 * (2)配置映射关系
		 * (3)创建核心配置文件,引入映射文件
		 * (4)调用service,在service调用dao
		 * (5)在dao实现列表的操作(hibernate代码实现)
		 */
		List<Customer> list = new ArrayList<Customer>();
		Customer c1 = new Customer();
		c1.setCustName("百度");
		c1.setCustSource("web");
		c1.setCustPhone("111");
		c1.setCustMobile("222");
		
		Customer c2 = new Customer();
		c2.setCustName("阿里巴巴");
		c2.setCustSource("web");
		c2.setCustPhone("555");
		c2.setCustMobile("333");
		
		list.add(c1);
		list.add(c2);
		
		//servlet里面 放到域对象里面 request域里面
		HttpServletRequest request = ServletActionContext.getRequest();
		request.setAttribute("list", list);

		return "list";
	}

第二节

1.注意

在这里插入图片描述
项目中的默认hibernate和Struts的xml文件名注意是小写的
在这里插入图片描述

2.配置全局结果页面(在Struts.xml的package里面)

在这里插入图片描述
我们在action在配置的result标签,这个配置叫做局部结果页面。

3.result标签的type属性

1.result标签的作用:根据action的方法返回值进行配置,找到不同路劲里面
2.result标签里面name属性,和方法返回值对应
3.result标签的重要属性type
●表示如何到路劲中去(转发还是重定向)
●type属性默认值-----转发操作,dispatcher
●重定向操作:redirect
注意:之前在web阶段,写重定向的时候带项目名称,转发路劲不需要带项目名称
但是在structs2里面重定向不用写路劲不用带项目名。
4.上面两个值dispatcher和redire,两个值,一般都针对跳转到页面配置
那么action中的转发和重定向:
●chain:转发action
●redirectAction:重定向到action(这个比较常用)
在这里插入图片描述

4.Action获取表单数据

1.使用ActionContext类获取
2.使用ServletActionContext类获取
3.使用接口注入方式(了解)

●获取表单数据
使用ActionContext类得到request域对象来获取页面数据
在这里插入图片描述
在这里插入图片描述
●Action中对域对象的操作
在这里插入图片描述

使用ServletActionContext类获取

  • ServletActionContext类里面提供很多静态的方法,调用方法获取request对象,调用request里面的方法得到表单数据
public class ServletActionContextDemo extends ActionSupport {

	public String execute() throws Exception {
		//1 获取request对象
		HttpServletRequest request = ServletActionContext.getRequest();
		//2 调用request里面的方法获取表单数据
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		String address = request.getParameter("address");
		
		System.out.println(username+":"+password+":"+address);
		return NONE;
	}
}

5.Struts2提供的数据封装

(1)原始方式封装数据
(2)属性封装
1.使用属性封装,把表单提交数据封装到action的属性里面
2.底层实现:获取request对象,调用request的方法获取表单数据,设置到属性里面
3.具体实现

 3.1  在action中定义变量

在这里插入图片描述
3.2 生成action变量的set方法

在这里插入图片描述
在这里插入图片描述
(3)模型驱动封装(最常用的)
1.能把我们的数据封装到对象里面
在这里插入图片描述
2.实现步骤:
1)action实现接口ModeDriven
在这里插入图片描述
2)实现接口的方法
在这里插入图片描述
3)需要在action里面手动创建实体对象

●要求:实体类属性名称和表单里面name属性值一样

(4)表达式封装
在这里插入图片描述
(5)模型驱动封装和表达式封装数据的对比
●两个都可以封装数据到对象中
模型驱动封装:只能把数据封装到一个对象中
表达式封装:可以把数据封装到多个对象

5.向表单中封装集合

1.封装数据到list集合
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2.封装数据到map集合
action中的步骤:
1)定义一个变量
2)生成get和set集合
3)在方法里面执行
在这里插入图片描述
表达式中的:
在这里插入图片描述

第三节:值栈和ognl

●Struts2的默认的表达式语言(类似jsp里面的el表达式),主要和Struts2的标签一起用用来操作值栈。
OGNL本身不是Struts2一部分,只是它通常在Struts2中用来值栈。
使用ognl需要导入jar包,这个jar包在struts2框架提供出来

1.值栈

●什么是值栈:
1 之前在web阶段学习过域对象,可以使用域对象存值和取值
(1)在servlet里面把数据放到域对象里面
(2)在jsp页面中使用el表达式获取域对象里面值

2 现在使用action,在action操作域对象
(1)在action可以把数据放到域对象里面,在jsp页面使用el表达式获取到

3 struts2里面提供存储机制是值栈,类似于域对象,可以存值和取值
(1)在action可以把数据放到值栈中,在jsp页面通过struts2标签+ognl表达式获取值

3 Servlet和Action区别
(1)servlet默认在第一次访问时候创建,创建一次,单实例对象
(2)action在每次访问时候都会一个action对象,创建多次,多实例对象

2.获取值栈对象

1 值栈对象存值于每个action对象里面,所以在action获取到值栈对象
2 在action里面封装对象ActionContext,使用ActionContext可以获取值栈对象(常用)
在这里插入图片描述
3 验证每个action对象里面只有一个值栈对象
在这里插入图片描述在这里插入图片描述

3.值栈的内部结构:(ctrl+shift+T查找方法)

第一部分–>root:
1)继承Arraylist:他是一个list集合
2)
第一部分–>context:
1)继承Map:他是一个map集合
2)在context里面主要储存对象的引用
在这里插入图片描述
1 值栈分为两部分:
(1)root是list集合,一般操作都是root里面内容
(2)context是map集合

2 struts2里面标签 s:debug,使用这个标签可以查看值栈结构和存储值
(1)通过action跳转到页面,在页面中使用struts2里面debug标签
(2)默认情况下,值栈中栈顶元素是action对象引用
在这里插入图片描述
值栈结构:
(1)每个action对象里面有一个值栈对象
(2)每个值栈对象里面有action对象引用

5.向值栈放数据

1 在action里面可以把数据放到值栈里面,在jsp页面中使用struts2标签+ognl表达式获取
2 向值栈放数据有三种方式
第一种 获取值栈对象,调用值栈对象里面set方法
在这里插入图片描述
第二种 获取值栈对象,调用值栈对象里面push方法
在这里插入图片描述
第三种(常用) 在action定义变量,生成变量get方法

/**

 * 第三种方式放数据

 * @author asus

 *

 */

public class ValueStackDemo2 extends ActionSupport {


//1 定义变量

private String username;

//2 get方法

public String getUsername() {

return username;

}

 

public String execute() throws Exception {

//3 向username设置值

username = "wwwbbccc";

return "demo2";

}

}

在这里插入图片描述
栈顶元素还是action对象引用,action里面有变量,不需要向值栈里面做压栈操作

在这里插入图片描述
在这里插入图片描述
验证每个action对象里面只有一个值栈对象
1 值栈对象存值于每个action对象里面,所以在action获取到值栈对象
2 在action里面封装对象ActionContext,使用ActionContext可以获取值栈对象(常用)
在这里插入图片描述
3 验证每个action对象里面只有一个值栈对象
在这里插入图片描述
6.获取字符串

9.2 获取对象

1 向值栈放字符串

//1 定义变量

private String username;

//2 get方法

public String getUsername() {

return username;

}

public String execute() throws Exception {

//3 向username设置值

username = "wwwbbccc";

return "demo2";

}

在这里插入图片描述

1 向值栈放对象

//1 定义user类型变量

private User user = new User();

//2 生成get方法

public User getUser() {

return user;

}

public String execute() throws Exception {

//3 向user对象里面设置值

user.setUsername("rose");

user.setPassword("250");


return "object";

}

2 在jsp页面中获取值栈对象值

在这里插入图片描述

9.3 获取list集合

//1 定义list集合类型变量

private List<User> list = new ArrayList<User>();

//2 get方法

public List<User> getList() {

return list;

}

 

public String execute() throws Exception {

//3 设置list集合值

User user1 = new User();

user1.setUsername("小金");

user1.setPassword("55555");


User user2 = new User();

user2.setUsername("小奥");

user2.setPassword("9999999");

list.add(user1);

list.add(user2);
return "list";
}

1 有三种方式获取
第一种(了解)
在这里插入图片描述

<!-- 第一种方式 -->

<s:property value="list[0].username"/>

<s:property value="list[0].password"/>

<br/>

<s:property value="list[1].username"/>

<s:property value="list[1].password"/>


(1)第二种和第三种方式,使用struts2里面标签实现
s:iterator标签,类似于jstl里面forEach标签
s:iterator标签在jsp页面中遍历值栈list集合数据

第二种
在这里插入图片描述

<!-- 第二种方式

<c:forEach items="${list}" var="user">

  ${user.username}

</c:forEach>

 -->

 <s:iterator value="list">

 	<!-- 遍历list集合,得到集合里面每个user对象

 	直接写user对象里面属性名称

 	 -->

 	<s:property value="username"/>

 	<s:property value="password"/>

 </s:iterator>

第三种

<s:iterator value=“list”>

<!-- 遍历list集合,得到集合里面每个user对象

直接写user对象里面属性名称

 -->

<s:property value="username"/>

<s:property value="password"/>

</s:iterator>

第三种
 <!-- 第三种方式
 	添加var之后,iterator标签里面做优化操作
 	(1)操作值栈list集合在值栈root里面
 	(2)遍历list集合从root里面把list集合获取到
 	(3)机制:
 	 添加var属性之后,每次遍历list集合得到user对象,
 	 把获取user对象放到context里面
 	 最终获取每次遍历user对象值,从context里面获取
 	 (4)从context里面获取值,写ognl表达式,表达式前面添加符号 
 	  	优化思想:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201224211034845.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTQ2OTIyMjQ=,size_16,color_FFFFFF,t_70)

```java
<s:iterator value="list" var="user">

 	<s:property value="#user.username"/>

 	<s:property value="#user.password"/>

 	<br/>

 </s:iterator>

1 在jsp页面使用el表达式从值栈把值获取出来

在这里插入图片描述
2 为什么可以获取
(1)文字描述:
底层对request对象里面的getAttribute方法进行增强

  • 首先从request域获取值,如果可以获取到直接返回
  • 如果从request域获取不到值,到值栈把值获取到,把值放到域对象里面

(2)源代码:

  • 调用request里面getAttribute方法获取域对象里面值
    在这里插入图片描述
  • 如果获取到,直接返回在这里插入图片描述
  • 如果获取不到
    在这里插入图片描述
  • 获取值栈对象,从值栈里面把值获取到,放到request域里面

在这里插入图片描述
1 #从context获取值
(1)在action向域对象里面放值,在jsp页面中使用ognl表达式获取

/**

 * 向request域里面放值

 * @author asus

 *

 */

public class ContextDemo extends ActionSupport {


@Override

public String execute() throws Exception {

ServletActionContext.getRequest().setAttribute("req", "reqValueValue");
return "context";

}

}

<!-- 值栈获取request里面值 -->

<s:property value="#request.req"/>

1 在struts2标签里面有表单标签

1)在struts2的表单标签里面使用ognl表达式,必须添加%,不能使用
(2)写%之后,让struts2表单标签value属性内容作为ognl执行
在这里插入图片描述

1 过滤链
(1)一个请求有多个过滤器进行过滤,每个过滤器只有放行操作,才能到下一个过滤器

第四节:拦截器

1 struts2是框架,在struts2框架里面封装很多功能,struts2里面功能在拦截器里面封装,
封装很多功能,每个封装的功能都会对应一个拦截器
比如 模型驱动,属性封装,这些都是在拦截器封装的功能
2 struts2里面封装了很多的功能,有很多的拦截器,这些拦截器不是都会执行,每次访问时候执行一些默认拦截器
3 struts2里面默认拦截器位置
在这里插入图片描述
4 拦截器在什么时候执行
(1)在action对象创建之后,action里面的方法执行之前执行拦截器

拦截器底层原理

1 拦截器底层使用两个原理
第一个 aop思想(动态代理)
(1)面向切面(方面)编程
(2)在基本功能之上,添加功能,不修改源代码实现,一般使用配置实现
(3)举例说明:

  • 登录为例,有登录表单页面,输入用户名和密码,提交表单到servlet里面,在servlet获取用户名和密码,查询数据库判断
  • 在登录基本功能添加角色判断,使用原始方式修改源代码实现,通过配置方式完成

在这里插入图片描述
第二个 责任链模式
(1)类似于之前过滤链
一个请求有多个过滤器进行过滤,每个过滤器只有放行,才能到下一个过滤器
在这里插入图片描述
(2)责任链模式:
责任链模式是java设计模式
比如一组操作,有添加,修改操作,
首先执行添加操作,添加操作执行之后做类似于放行操作,执行修改操作
每个功能执行之后,做类似于放行操作,执行下一个操作

2 aop思想和责任链模式如何应用到拦截器里面?
文字描述:
(1)拦截器在action对象创建之后,action的方法执行之前执行
(2)每次访问action时候,创建action对象,执行action方法之前,执行struts2里面默认拦截器,
(3)首先用到aop思想:在action里面没有直接调用拦截器方法,通过配置方式执行
(4)其次用到责任链模式:执行很多拦截器,假如有三个拦截器,这三个拦截器都会执行,
首先执行拦截器1,拦截器1执行之后做放行操作,执行拦截器2,拦截器2执行之后做放行,执行拦截器3,拦截器3执行之后做放行,执行action里面的方法

画图分析
在这里插入图片描述

3 查看源代码

(1)执行action
在这里插入图片描述
(2)创建action对象,使用动态代理方式
在这里插入图片描述
(3)执行action的方法
在这里插入图片描述
(4)执行很多的拦截器,遍历执行
在这里插入图片描述
类似于放行的操作的方法
在这里插入图片描述

4 struts2执行流程

在这里插入图片描述
(1)发送请求,到struts2过滤器,读取配置文件
在这里插入图片描述
(2)创建action代理对象

在这里插入图片描述
(3)执行action里面的方法,执行很多拦截器
在这里插入图片描述
(4)执行action的方法
在这里插入图片描述
(5)根据返回值做响应操作,执行这些拦截器,执行顺序
在这里插入图片描述

重要的概念

1 过滤器和拦截器区别
(1)过滤器可以过滤任意内容,比如jsp、html、servlet、图片路径
(2)拦截器只能拦截action

2 Servlet和action区别
(1)servlet单实例对象
(2)action多实例对象

自定义拦截器

1 在struts2里面有很多的拦截器,在实际开发中,有的功能在拦截器可能没有封装,可以自己写拦截器实现功能封装

2 拦截器结构
(1)通过源代码查看
继承类
在这里插入图片描述
继承类实现接口,有三个方法
在这里插入图片描述
在这里插入图片描述
2)开发中,建议使用另外一种方式
继承 MethodFilterInterceptor类实现
好处:通过配置方式让action某些方法不进行拦截

(3)自己写拦截器,需要配置方式让拦截器对action进行拦截

自定义登录拦截器

1 需求:在项目中有很多action超链接,只有登录状态点击超链接实现功能,如果不是登录状态,点击action超链接,跳转到登录页面

2 使用session域对象登录状态判断
(1)在登录成功之后,把登录信息放到session域对象里面
(2)判断是否登录,判断session是否有值

3 登录基本功能实现
(1)使用图片提交,和type=”submit”效果一样的
在这里插入图片描述
(2)action写登录的方法

/属性封装获取用户名和密码

private String username;

private String 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 String login() {

/*

 * 直接判断

 * admin  250

 * */

if("admin".equals(username) && "250".equals(password)) {

//成功

//使用session域对象

HttpSession session = ServletActionContext.getRequest().getSession();

session.setAttribute("username", username);

//	ActionContext context = ActionContext.getContext();

//	context.getSession().put("username", username);

return "loginsuccess";

} else {

//失败

return "login";

}

}

(3)使用session域对象登录状态

在这里插入图片描述

(4)在主页面里面显示当前登录用户名

4 自定义登录拦截器实现过程

第一步 创建类,继承MethodFilterInterceptor类

第二步 重写类里面拦截的方法,写拦截器逻辑

(1)判断是否是登录状态,判断session域里面是否有名称是username值

/**

 * 登录拦截器

 *

 */

public class LoginInterceptor extends MethodFilterInterceptor{

 

//做拦截的方法,写拦截器逻辑

protected String doIntercept(ActionInvocation invocation) throws Exception {

// 判断是否是登录状态,判断session域里面是否有名称是username值

HttpSession session = ServletActionContext.getRequest().getSession();

Object obj = session.getAttribute("username");

//判断

if(obj != null) {//登录

//做类似于放行操作

return invocation.invoke();

} else {//不是登录

//回到登录页面

return "login";

}

}

}

第三步 配置方式让自定义登录拦截器和action建立关系(注册拦截器)
aop思想体现
(1)在struts.xml中package标签里面声明(定义)拦截器

在这里插入图片描述

<!-- 1 声明拦截器 -->

<interceptors>

<interceptor name="loginintercept" class="cn.itcast.interceptor.LoginInterceptor"></interceptor>

</interceptors>


(2)在action标签里面使用声明的拦截器

  • 对哪个action进行拦截,在那个action标签里面使用声明拦截器

    (3)特点:如果在action标签里面使用自定义拦截器,struts2里面默认的拦截器不会执行了,手动把默认拦截器在action标签里面配置一次
<!-- 3 让默认拦截器手动配置一次 -->

<interceptor-ref name="defaultStack"></interceptor-ref>

5 上面配置,对action里面所有方法进行拦截

(1)在action有登录的方法,登录的方法不需要拦截,登录方法拦截,永远不能登录
(2)继承MethodFilterInterceptor,使用配置方式让action里面某些方法不进行拦截
(3)可以让action里面login方法不进行拦截

<!-- 2 使用自定义拦截器 -->
<interceptor-ref name="loginintercept">
<!-- param标签,name属性值  excludeMethods ,标签里面写不进行拦截的方法名称
可以写多个方法  方法1,方法2

-->
<param name="excludeMethods">login</param>
</interceptor-ref>

在这里插入图片描述

6 最终测试:

(1)出现问题:页面套页面问题
在这里插入图片描述
(2)在form标签里面使用target设置打开位置

<?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="demo" extends="struts-default" namespace="/">
		<!-- 1 声明拦截器 -->
		<interceptors>
			<interceptor name="loginintercept" class="cn.itcast.interceptor.LoginInterceptor"></interceptor>
		</interceptors>
		
		<action name="customer_*" class="cn.itcast.action.CustomerAction" method="{1}">
			<!-- 2 使用自定义拦截器 -->
			<interceptor-ref name="loginintercept">
				<!-- param标签,name属性值  excludeMethods ,标签里面写不进行拦截的方法名称
					可以写多个方法  方法1,方法2
				-->
				<param name="excludeMethods">login</param>
			</interceptor-ref>
			
			<!-- 3 让默认拦截器手动配置一次 -->
			<interceptor-ref name="defaultStack"></interceptor-ref>
			
			<result name="list">/jsp/customer/list.jsp</result>
			<!--添加页面  -->
			<result name="toAddPage">/jsp/customer/add.jsp</result>
			<result name="addCustomer">/jsp/success.jsp</result>
			
			<!-- 登录 -->
			<result name="loginsuccess">/index.htm</result>
			<result name="login">/login.jsp</result>
		</action>
	</package>
</struts>

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值