Struts2概述
1、struts2框架应用于javaee三层结构中web层框架
2、struts2框架是在struts1和webwork基础上发展全新的框架
3、struts2解决问题
web层常见框架
1、struts
2、springMVC
导入jar包:
下载struts2-all,解压文件lib文件夹中是jar包,src中是源码。
不能把所有jar导入,在apps中找到示例程序,从示例程序中复制jar包就可以。
创建action:
public class ActionTest {
//每次访问servlet的时候,都会执行service方法
//写继承HttpServlet,重写里面的方法,在web.xml中配置serlvet访问路径
//现在要访问的是action,每次访问action的时候,默认执行execute方法
public String execute(){
return "ok";
}
}
配置action类访问路径
- 创建一个struts2核心配置文件,核心配置文件名称和位置固定,位置必须在src下面,名称struts.xml;
- 引入DTD约束,可以在示例程序中找到
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
配置文件
<struts>
<package name="hellodemo" extends="struts-defaule" namespace="/">
<!-- name:访问名称-->
<action name="hello" class="cn.it.action.helloAction">
<!-- 配置方法返回值到不同的页面中去-->
<!-- /hello.jsp是跳转的页面路径-->
<result name="ok">/hello.jsp</result>
</action>
</struts>
配置过滤器
在示例程序的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>
配置过滤器类:StrutsPrepareAndExecuteFilter
过滤器在服务器启动的时候创建,过滤器在创建的时候执行里面的init()方法
在init方法中主要加载文件,包含自己创建的文件和struts2自带的配置文件
struts.xml和web.xml
struts2里面的配置
核心配置文件:
标签package
类似于代码包,用于区分不同的action,哟配置action,必须写package
属性name name属性的值跟功能本身是没有关系的,在一个配置文件中,可以写多个package属性值,多个package属性值名称不能相同。
属性extends 继承,struts-defaule,这个值是固定的,表示写了这个属性之后,在package配置的类具有action的功能
属性namespace 名称空间,属性值和action标签里面的name属性值过程访问路径。
标签action
配置action访问路径
属性name 在一个package标签可以写多个action标签,但是action的name属性值不能相同,和package的属性namespace 构成访问路径
属性class action全路径
属性method 比如在action里面默认执行的方法是execute方法,但是如果有其他方法,用这个属性指定执行其他方法
标签result
根据你action的返回值,配置到不同的路径中去
result属性:
name:和方法的返回值一样
type:配置如何到路径中去(转发或者重定向),type属性的默认值是转发操作。
struts2常量配置
<constant name="struts.i18n.encoding" value="utf-8"></constant>
常用的常量:
struts.i18n.encoding=UTF-8
1、表单提交数据到action里面,在action可以回去表单提交数据
2、表单提交数据有中文,有乱码问题。post提交直接设置编码,get提交要坐编码转换,如果在action获取表单通过post方式提交中文,中文乱码问题会帮我们处理,不需要自己处理。
分模块开发:
单独写配置文件,把配置文件引入到核心配置文件中来。
<!-- 引入配置.xml文件-->
<include file="cn/it/action/hello.xml"></include>
action的编写方式
action有三种编写方式
1、第一种:创建普通类,这个类不继承任何类,也不实现任何接口;
2、创建类实现接口,Action接口;
import com.opensymphony.xwork2.Action;
public class ActionTest implements Action{
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
return null;
}
}
3、创建类,继承类,ActionSupport类。
public class ActionTest extends ActionSupport{
}
访问action中的方法
有三种方式:
1、使用action标签的method属性,在这个属性里面写执行的action的方法
2、使用通配符的方式实现
在cation标签里面name属性,name属性值里面写符号“*”,表示可以匹配任意内容
<action name="book_*">
<action name="*">
上面两种方式都可以
然后写method的属性值
<action name="book_*" method="{1}"> 表示取第一个星号,name可以有多个星号
3、动态访问实现(不用)
在action中方法有返回值,有返回值必须是String类型;
没有返回值,在result标签中就不需要配置。(把方法写成void或者让返回值返回值返回“none”,action中有常量NONE,需要实现ActionSupport)
结果页面配置
1、result标签配置action方法的返回值到不同的路径里面
创建两个action,执行默认方法execute方法,让两个action的方法都返回success,返回success之后,配置到同一个页面里面
如果有多个action,他们返回值相同,到相同的页面,这个时候要用全局结果页面,只作用在package标签中
配置文件:
<package name ="demo1" extends="struts-default" namespace="/">
<action name="book" class="cn.it.action">
<result name="success">/hello.jsp</result>
</action>
<action name="oders" class="cn.it.Orderaction">
<result name="success">/hello.jsp</result>
</action>
</package>
改为全局结果配置:
<package name ="demo1" extends="struts-default" namespace="/">
<global-results>
<result name="success">/hello.jsp</result>
</global-results>
<action name="book" class="cn.it.action">
</action>
<action name="oders" class="cn.it.Orderaction">
</action>
</package>
局部结果页面
<package name ="demo1" extends="struts-default" namespace="/">
<global-results>
<result name="success">/hello.jsp</result>
</global-results>
<action name="book" class="cn.it.action">
</action>
<action name="oders" class="cn.it.Orderaction">
</action>
</package>
上面程序既配置了全局结果页面,也配置了局部结果页面,以局部结果页面为准
Result标签中的type属性
type属性表示配置如何到路径中去(转发还是重定向)
type的属性值:
1、默认值(转发操作,dispatcher)
2、重定向(redirect)
type属性配置到其他action中
3、chain 转发到action,一般不用,缓存问题
4、redirectAction 重定向到action
<package name ="demo1" extends="struts-default" namespace="/">
<action name="book" class="cn.it.action">
<!-- type属性转发重定向到action-->
<result name="success" type="redirect">orders</result>
</action>
<action name="oders" class="cn.it.Orderaction">
<result name="success">/hello.jsp</result>
</action>
</package>
获取表单数据
struts提供获取表单数据的方式:
1、使用ActionContext类
//String是表单中name值,Object是输入项的值
//Map<String, Object> getParameters();
//注意:根据key获取的Object是数组Object[],因为输入项可能是复选框的形式,所以是数组。
//使用static ActionContext getContext()方法获取当前线程的ActionContext
2、使用ServletActionContext类
static HttpServletRequest getRequest();
static HttpServletResponse getResponse();
static ServletContext getServletContext();
static PageContext getPageContext()
3、使用接口注入方式
让action实现一个接口,通过这个接口得到Request
//ServletRequestAware
//ServletResponseAware
//SessionAware
//ServletContextAware
列表
CustomerService service = new CustomerService();
List<Customer> list = service.finaAll();
在action操作域对象
1、request、session、servletContext对象
2、使用ServletActionContext对象
struts的数据封装:
1、属性驱动封装
1、在action类中定义几个成员变量,变量名要和表单输入项name属性一样
2、生成这些变量的set和get方法
可以直接把表单提交属性封装到action的属性里面
使用属性封装获取表单数据到属性里面,不能把数据直接封装到实体类对象里面
2、模型驱动封装(主要用这个)
前提要求:表单输入项name属性值和实体类属性名称一样
可以直接把表单的数据封装到实体类对象里面
步骤:
1、action实现ModelDrive接口
2、实现接口里面的方法getModel方法
3、在action中创建实体类对象
使用模型驱动和属性封装注意问题:
- 1、在一个action中不能同时使用属性封装和模型封装,如果同时使用,只会执行模型驱动
3、表达式的封装
实现过程:
1、使用表达式封装可以把表单数据封装到实体类对象里面
第一步:在action里面声明实体类
声明User类:private User user;
在配置中input的name属性值:user.属性名
第二步:生成实体类变量的set和get方法
第三步:表单中的name写成表达式
比较表达式封装和模型驱动封装:
1、使用表达式封装和模型驱动封装都可以把数据封装到实体类对象里面
2、不同:使用模型驱动只能把数据封装到一个实体类对象里面,在一个action里面不能使用模型驱动把数据封装到不同的实体类对象中;使用表达式封装可以把数据封装到不同的实体类对象中。
获取表单数据封装到集合中:
1、封装到list集合
2、封装到map集合
Ognl
值栈:值栈是对应每一个请求对象的轻量级内存数据中心。
请有请求到达的时候,Struts2会为每个请求创建一个新的值栈,也就是值栈和请求是一一对应的,不同的请求,值栈也不一样,而值栈封装了一次请求所有需要操作的相关数据。
Struts2中,值栈有风广义和狭义:
1、狭义值栈:通常指实现com.opensymphony.xwork2.util.ValueStack接口对象,目前就是com.opensymphony.xwork2.ognl.OgnlValueStack对象。
狭义值栈主要用来存取动态EL(表达式语言)运算需要的值和结果,OgnlValueStack对象主要是用来支持OGNL(对象图导航语言)运算的。
狭义值栈里面存放着一些OGNL可以存取访问的数据。
2、广义值栈:通常指ActionContext对象,ActionContext是线程安全的,每个线程有一个独立的ActionContext。
servlet和action的区别:
1、Servlet默认在第一次访问的时候创建,创建一次,单实例对象
2、Action:访问的时候创建,每次访问action时候,都会创建一个action对象。多实例对象
值栈分为两部分:
1、root,结构是list集合,一般操作root中的数据
2、context,结构是map集合,存储对象的引用
值站存储位置
获取值栈对象方式:
1、使用ActionContext类里面的方法得到值栈对象
调用ActionContext类的getValueStack()方法,得到值栈对象
获取之后使用值栈:
get(String key):根据key从ActionContext当前的存储空间里面获取相应的值
put(String key):把值存储在ActionContext的存储空间里面
Map<String,Object> getApplication():返回ServletContext中存储的值
Map<String,Object> getSession():返回HttpSession中存储的值
Map<String,Object> getContextMap():返回当前context存储的值
Map<String,Object> getParameters():返回HttpServletRequest对象中存储的值
ValueStack getValueStack():获取OGNL值栈
向值栈中存数据
1、获取值栈对象,调用值栈对象里面的set方法
2、获取值栈对象,调用值栈对象里面的push方法
3.在action定义变量,生成变量的get方法
向值栈中获取数据
使用struts 2标签加OGNL表达式获取值栈数据
1、<s:property value="ognl表达式">
2、获取对象
3、获取list
OGNL的# 和 %的使用
#的使用:
拦截器
struts2是框架,封装了很多功能,struts封装的功能都是在拦截器里面封装的,struts2封装了很多功能,有很多拦截器,不是每次这些拦截器都执行,每次执行默认的拦截器。struts2默认拦截器的位置:struts-default.xml
拦截器,在action对象创建之后,action方法执行之前执行
拦截器底层原理:使用两个原理
1、aop思想
aop:面向切面编程(面向方面编程),
2、责任链模式
在action方法执行之前执行默认拦截器,执行过程使用aop思想,在cation没有直接调用拦截器的方法,使用配置文件方式进行操作。
在执行拦截器时候,执行很多的拦截器,这个过程使用责任链模式
过滤器和拦截器的区别:
1、过滤器理论上可以过滤任意内容,比如html、jsp、图片路径等
2、拦截器只可以拦截action
Servlet和action的区别:
1、servlet默认第一次访问的时候创建,创建一次,单实例对象
2、action每次访问时候创建,创建多次,多实例对象
自定义拦截器
在struts2有很多拦截器,这些拦截器是struts2封装的功能,但在实际开发中struts2里面的拦截器中可能没有要使用的功能,这个时候需要自己写拦截器实现功能。
开发中继承MethodFilterInterceptor类,可以让action里面的某个方法不能拦截,然后通过配置文件,让拦截器和action有关系
Struts2标签库:
struts2标签使用jsp页面中
s:property:和ognl表达式在jsp页面中获取值栈数据
s:debug查看值栈结构和数据