第一节
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层框架特点
- 只要框架是应用在web层框架,这类框架共同特点:有前端控制器(过滤器)
- 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表达式,表达式前面添加符号
优化思想:

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