<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
(1)有三种
(2)一般使用继承类 ActionSupport实现
public class LoginAction extends ActionSupport{}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<!-- struts默认样式是xhtml -->
<!-- <constant name="struts.ui.theme" value="simple"/> -->
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
<!-- 国际化文件配置 -->
<constant name="struts.custom.i18n.resources" value="message"/>
<!-- 设置编码格式 -->
<constant name="struts.i18n.encoding" value="UTF-8"/>
<!-- 创建一个default包,继承自Struts2的struts-default包 -->
<package name="default" namespace="/" extends="struts-default">
<interceptors>
<!--登录验证的拦截器 -->
<interceptor name="login" class="com.jredu.interceptor.LoginInterceptor"></interceptor>
<!-- 自定义拦截器栈 -->
<interceptor-stack name="loginStack">
<interceptor-ref name="login">
<param name="excludeMethods">login</param>
</interceptor-ref>
<!-- 把原先默认拦截器栈加入到mystack拦截器 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 设置默认拦截器 -->
<default-interceptor-ref name="loginStack"></default-interceptor-ref>
<!-- 全局result -->
<global-results>
<result name="success">success.jsp</result>
<result name="login">login.jsp</result>
</global-results>
<!-- 配置一个Helloaction -->
<action name="hello" class="com.jredu.action.HelloAction">
<result name="hello">/index.jsp</result>
</action>
<action name="login" class="com.jredu.action.LoginAction" method="execute2">
<result name="success">success.jsp</result>
<result name="fail">fail.jsp</result>
</action>
</package>
</struts>
Struts2的核心配置文件:
1 名称和位置固定的
2在配置文件中主要三个标签 package、action、result,标签里面的属性1 类似于代码包,区别不同的action,要配置action,必须首先写package标签,在package里面才能配置action
2 package标签属性
(1)name属性
- name属性值根功能本身没有关系的,
- 在一个配置文件中可以写多个package标签,name属性值不能相同的
(2)extends属性
- 属性值固定的,struts-default
- 写了这个属性之后,在package里面配置的类具有action功能
(3)namespace属性
-namespace属性值和action标签里面的name属性值构成访问路径
<package name="default" namespace="/" extends="struts-default"></package>
标签action:
1action标签配置action访问路径
2action标签属性
(1)name属性
- namespace属性值和action标签里面的name属性值构成访问路径
- 在package标签里面写多个action标签,但是action的name属性值不能相同的
(2)class属性
- action全路径
(3)method属性
- 比如在action里面默认执行的方法execute方法,但是在action里面写其他的方法
-让action里面多个方法执行,使用method进行配置<action name="login" class="com.jredu.action.LoginAction" method="execute2">
<result name="success">success.jsp</result>
<result name="fail">fail.jsp</result>
</action>
标签result:
1 根据action的方法返回值,配置到不同的路径里面
2result标签属性
(1)name属性
- 和方法返回值一样
<result name="success">success.jsp</result>
(2)type属性
1result标签里面除了name属性之外,还有一个属性 type属性
(1)type属性:如何到路径里面(转发还是重定向)
2 type属性值
(1)默认值,做转发操作,值是 dispatcher
(2)做重定向操作,值是 redirect
(3)上面两个值dispatcher、redirect,这两个值一般针对到页面中配置,
配置到其他的action里面
- chain:转发到action,一般不用,缓存问题
-redirectAction:重定向到action
<!-- type默认值是dispatcher,设置redirect为重定向 -->
<action name="redirect" class="com.jredu.action.RedirectAction">
<result name="success" type="redirect">redirect.jsp</result>
<result name="error" type="redirectAction">redirect2</result>
</action>
Struts2常量配置:
1struts2框架,帮我们实现一部分功能,struts2里面有常量,在常量里面封装一部分功能
2struts2默认的常量位置(记住)
3 修改struts2默认常量值
(1)常用的方式
- 在struts.xml中进行配置
<!-- 设置编码格式 -->
<constant name="struts.i18n.encoding" value="UTF-8"/>
(2)还有两种方式(了解)
- 在src下面创建 struts.properties,进行修改
- 在web.xml进行配置
Action编写方式:
第一种创建普通类,这个不继承任何类,不实现任何接口
第二种创建类,实现接口 Action
第三种创建类,继承类 ActionSupport(一般使用)
访问action的方法:
1 有三种方式实现
第一种使用action标签的method属性,在这个属性里面写执行的action的方法
第二种使用通配符方式实现
第三种 动态访问实现(不用)(1)如果action方法有返回值,在配置文件中没有配置,出现错误
(2)在action里面的方法有返回值,如果有返回值时候类型必须是String
(3)action里面的方法可以没有返回值,没有返回值时候,在result标签不需要配置
- 把方法写成void
- 让返回值,返回 ”none”(常用)
使用通配符实现:
<action name="change*" class="com.jredu.action.ChangeAction" method="{1}">
</action>
全局结果页面:
1result标签配置action方法的返回值到不同的路径里面
2 创建两个action,执行默认的方法execute方法,让两个action的方法都返回success,返回success之后,配置到同一个页面里面
(1)如果多个action,方法里面返回值相同的,到页面也是相同的,这个时候可以使用全局结果页面配置
(2)在package标签里面配置
<!-- 全局result -->
<global-results>
<result name="success">success.jsp</result>
<result name="login">login.jsp</result>
</global-results>
Action获取表单提交数据:
1 之前web阶段,提交表单到servlet里面,在servlet里面使用request对象里面的方法获取,getParameter,getParameterMap
2 提交表单到action,但是action没有request对象,不能直接使用request对象
3 action获取表单提交数据主要三种方式
(1)使用ActionContext类
(2)使用ServletActionContext类(常用)
(3)使用接口注入方式 public String execute(){
if("admin".equals(username)&&"123456".equals(pwd)){
Map<String,Object> sessionMap = ActionContext.getContext().getSession();
sessionMap.put("username", username);
return "success";
}else{
return "fail";
}
}
public String execute2(){
System.out.println("调用了这个方法");
if("admin".equals(username)&&"123456".equals(pwd)){
HttpSession session=ServletActionContext.getRequest().getSession();
session.setAttribute("username", username);
return "success";
}else{
return "fail";
}
}
在action操作域对象:
1 request、session、servletContext域对象
2 使用ServletActionContext类操作
Struts2封装获取表单数据方式:
1 直接把表单提交属性封装到action的属性里面
2 实现步骤
(1)在action成员变量位置定义变量
- 变量名称和表单输入项的name属性值一样
(2)生成变量的set方法(把set和get方法都写出来)
3 使用属性封装获取表单数据到属性里面,不能把数据直接封装到实体类对象里面public class HelloAction {
private String name;
private String message;
/*
* 当struts action处理请求时,在默认情况下调用execute方法
*/
public String execute(){
//把前台传入的名字拼接成完整的信息再返回给前台
setMessage("hello,"+getName()+"!");
return "hello";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
模型驱动封装:
1 使用模型驱动方式,可以直接把表单数据封装到实体类对象里面
2 实现步骤
(1)action实现接口ModelDriven
(2)实现接口里面的方法 getModel方法
- 把创建对象返回
(3)在action里面创建实体类对象
3 使用模型驱动和属性封装注意问题:
(1)在一个action中,获取表单数据可以属性封装,使用模型驱动封装,
不能同时使用属性封装和模型驱动封装获取同一个表单数据
如果同时使用,之后执行模型驱动public class Login5Action extends ActionSupport implements ModelDriven<User> {
private User user=new User();
@Override
public User getModel() {
// TODO Auto-generated method stub
return user;
}
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
System.out.println(user);
return NONE;
}
}
表达式封装:
1 实现过程
(1)使用表达式封装可以把表单数据封装到实体类对象里面
第一步在action里面声明实体类
第二步生成实体类变量的set和get方法
第三步在表单输入项的name属性值里面写表达式形式
public class Login2Action extends ActionSupport{
private User user;
public String login(){
if("admin".equals(user.getUsername())&&"123456".equals(user.getPwd())){
Map<String,Object> sessionMap = ActionContext.getContext().getSession();
System.out.println(user);
sessionMap.put("user",user);
return "success";
}else{
return "fail";
}
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
<form action="login2.action">
<input type="text" name="user.username"/>
<input type="password" name="user.pwd"/>
<input type="submit" value="登录"/ >
</form>
OGNL概述:
1 之前web阶段,学习过EL表达式,EL表达式在jsp中获取域对象里面的值
2 OGNL是一种表达式,这个表达式功能更加强大,
(1)在struts2里面操作值栈数据
(2)一般把ognl在struts2操作:和struts2标签一起使用操作值栈
3 OGNL不是struts2的一部分,单独的项目,经常和struts2一起使用
(1)使用ognl时候首先导入jar包,struts2提供jar包什么是值栈:
1 之前在web阶段,在servlet里面进行操作,把数据放到域对象里面,在页面中使用el表达式获取到,域对象在一定范围内,存值和取值
2 在struts2里面提供本身一种存储机制,类似于域对象,是值栈,可以存值和取值
(1)在action里面把数据放到值栈里面,在页面中获取到值栈数据
3servlet和action区别
(1)Servlet:默认在第一次访问时候创建,创建一次,单实例对象
(2)Action:访问时候创建,每次访问action时候,都会创建action对象,创建多次,多实例对象
4 值栈存储位置
(1)每次访问action时候,都会创建action对象,
(2)在每个action对象里面都会有一个值栈对象(只有一个)
向值栈放数据:
第一种获取值栈对象,调用值栈对象里面的 set 方法
第二种获取值栈对象,调用值栈对象里面的 push方法
第三种在action定义变量,生成变量的get方法
获取对象:
1 向值栈放对象
2在页面中获取值
获取list集合:
第一种方式:
第二种方式:
第三种方式:
EL表达式获取值栈数据:
1 EL表达式获取域对象值
2 向域对象里面放值使用setAttribute方法,获取值使用getAttribute方法
3 底层增强request对象里面的方法getAttribute方法
(1)首先从request域获取值,如果获取到,直接返回
(2)如果从request域获取不到值,到值栈中把值获取出来,把值放到域对象里面
OGNL的#、%使用:
2 演示# 操作
(1)向request域放值
(2)在页面中使用ognl获取
<s:radio name="user.sex.id" list="#request.listSex" listKey="id" listValue="name"></s:radio>
%使用
在struts2标签里面使用ognl表达式,如果直接在struts2表单标签里面使用ognl表达式不识别,只有%之后才会识别。
Struts2拦截器概述:
1struts2是框架,封装了很多的功能,struts2里面封装的功能都是在拦截器里面
2 struts2里面封装了很多的功能,有很多拦截器,不是每次这些拦截器都执行,每次执行默认的拦截器
3 拦截器在什么时候执行?
(1)在action对象创建之后,action的方法执行之前拦截器底层原理:
1 拦截器底层使用两个原理
第一个 aop思想
Aop是面向切面(方面)编程,有基本功能,扩展功能,不通过修改源代码方式扩展功能
第二个责任链模式
(1)在java中有很多的设计模式,责任链模式是其中的一种
(2)责任链模式和过滤链很相似的
责任链模式:
要执行多个操作,有添加、修改、删除三个操作。
首先执行添加操作,添加操作执行之后做类似于放行操作,执行修改操作,修改操作执行之后做类似于放行操作,执行删除操作
过滤链:一个请求可有多个过滤器进行过滤,每个过滤器只有做放行才能到下一个过滤器重要的概念:
1 过滤器和拦截器区别
(1)过滤器:过滤器理论上可以任意内容,比如html、jsp、servlet、图片路径
(2)拦截器:拦截器只可以拦截action
2 Servlet和action区别
(1)servlet默认第一次访问时候创建,创建一次,单实例对象
(2)action每次访问时候创建,创建多次,多实例对象自定义登录拦截器:
<interceptors>
<!--登录验证的拦截器 -->
<interceptor name="login" class="com.jredu.interceptor.LoginInterceptor"></interceptor>
<!-- 自定义拦截器栈 -->
<interceptor-stack name="loginStack">
<interceptor-ref name="login">
<param name="excludeMethods">login</param>
</interceptor-ref>
<!-- 把原先默认拦截器栈加入到mystack拦截器 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 设置默认拦截器 -->
<default-interceptor-ref name="loginStack"></default-interceptor-ref>
<!-- 全局result -->
<global-results>
<result name="success">success.jsp</result>
<result name="login">login.jsp</result>
</global-results>
public class Login2Action extends ActionSupport{
private User user;
public String login(){
if("admin".equals(user.getUsername())&&"123456".equals(user.getPwd())){
Map<String,Object> sessionMap = ActionContext.getContext().getSession();
System.out.println(user);
sessionMap.put("user",user);
return SUCCESS;
}else{
return LOGIN;
}
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
Struts2表单标签:
<body>
<h1>
<s:actionerror/>
</h1>
<s:form action="doRegister.action">
<table>
<tr>
<td>用户名:</td>
<td>
<s:textfield name="user.username"/>
</td>
</tr>
<tr>
<td>密码:</td>
<td>
<s:password name="user.pwd"/>
</td>
</tr>
<tr>
<td>性别:</td>
<td>
<s:radio name="user.sex.id" list="#request.listSex" listKey="id" listValue="name"></s:radio>
</td>
</tr>
<tr>
<td>爱好:</td>
<td>
<s:checkboxlist name="user.like.id" list="listLike" listKey="id" listValue="name"></s:checkboxlist>
</td>
</tr>
<tr>
<td>城市:</td>
<td>
<s:select name="user.city.id" list="listCity" listKey="id" listValue="name" headerKey="0" headerValue="--- 请选择----"></s:select>
</td>
</tr>
<tr>
<td colspan="2">
<s:submit value="提交"/>
</td>
</tr>
</table>
</s:form>
</body>