struts2

Struts2

●Struts2的来历
struts1:一个经典的MVC框架,缺点是与Servlet严重耦合,视图层的的封装很少
Struts2:是Apache在Struts1的基础上发展的,但核心是WebWork。可以说struts2=struts1的名气+webwork的实干
优点:采用拦截器的机制来处理用户的请求,使得业务逻辑控制器能够与ServletAPI完全脱离开

●struts2的工作流程
1)客户端初始化一个指向Servlet容器(例如Tomcat)的请求
2)请求被提交到一系列的过滤器组建链中
ActionContextCleanUp()→其他过滤器(SiteMesh等)→ FilterDispatcher
ActionContextCleanUp: 延长action中属性的生命周期,包括自定义属性,以便在jsp页面中进行访问,让actionContextcleanup过滤器来清除属性,不让action自己清除。
FilterDispatcher:Struts 2实现MVC中的控制层(Controller)的核心控制器
3)FilterDispatcher询问ActionMapper是否需要调用某个Action来处理这个(HttpServletRequest)请求,如果ActionMapper决定需要调用某个Action,FilterDispatcher则把请求的处理交给 ActionProxy。
4)ActionProxy(代理对象)通过Configuration Manager(struts.xml)询问框架的配置文件,找到需要调用的Action类。
5)ActionProxy创建一个ActionInvocation(调用器)实例,同时ActionInvocation通过代理模式调用Action。但在调用之前,ActionInvocation会根据配置加载Action相关的所有Interceptor(拦截器)。
6)Action执行完毕后,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果result。


这里写图片描述

1.项目搭建步骤:
a)导入jar包
b)配置文件
c)添加struts2的核心控件(过滤器)
d)写一个HelloAction
e)在struts.xml中配置action
f)访问action进行测试
在访问action时,地址可以写actionName.action也可以写actionName
2.struts.xml文件属性
名字:struts.xml 位置:src下面
内容 :
1)package
1)name:包名
2)namespce:访问路径 (分包,/表示当前项目路径)
(a) 查找命名空间下的 Action,首先是匹配命名空间,如果不匹配就一层层往上找,直到根命名空间为止,
(b)找不到就去在命名空间下查找匹配的action,匹配则执行,不匹配 ,则进入默认命名空间下,查找指定的 Action,找到则执行。如果找不到,Struts 2 程序出现异常。
3)extends:默认是继承struts-default这包
4)action
a)name:action的访问路径
b)lass:action的全类名(没有配置时由ActionSupport去处理)
c)method:类中的方法名称 (没有配置method的属性默认执行execute方法)
d)result
1)name:方法的返回值 (默认是success)
2)节点中间的内容:跳转的指定页面
3)type 属性:
ok.jsp type不写时,默认为dispatcher
1)dispatcher
a)只能转发到页面,不能转发到action
2)chain
a)只能转发到action,不能转发到页面
3)redirect
a)既可以重定向到页面又可以重定向到action,认url
4)redirectAction
a)指定重定向到Action
4)全局的result
先到当前的action节点中去找,找不到就到全局里面去找

ok.jsp



5)动态指定跳转或重定向到某地址
${ation中的属性名称}.jsp 属性要有get/set方法

3.action的实现方式
1)继承ActionSupport(常用,actionsupport实现了action接口)
2)实现Action接口 (重写了execute方法,所以struts.xml不写method属性)
3)普通Java类

4.表单中参数的传值方式
..可以动态传递参数,其实是存取值栈中的数据
1)action中直接写属性名称,一定要提供set/get方法,表单中要写属性名称
2)actino中写实体类的对象,一定要提供set/get对象的方法,表单中要写对象.属性(常用)
3)实现ModeDriven接口,实现getModel()方法返回对象,表单中写对象的属性(常用)
注意:不能在表单的action中传参数

4.1.值栈
ValueStack 是一个接口,它的实现类是ognlvalueStack,生命周期为一次请求.
结构:
root区(根节点,对象栈):保存当前访问的action对象(action是多例的,servlet是单例的)
ContextMap区(非根节点,上下文栈):保存了上下文各种映射关系,以map集合的方式存值
request-request作用域
session-session作用域
application-application作用域

a)方法
1)peek:查看栈顶,不移除对象
2)push:压栈
3)pop:弹栈,并且返回对象
4)set:把键值对放到了map,再将map放到了值栈中,页面通过key访问
b)如何使用
1)可以当成数据的载体
c)值栈的生命周期
生命周期就是一次请求(request)

5.action访问ServeltAPI
Action和Servlet解耦
1)通过ActionContext访问
a)返回的都是map
b)所有方法原生的,但是要调用get(StrutsStatics.HTTP_REQUEST)
2)通过ServeltActionContext访问(常用)
a)返回的都是原生的对象
3)通过实现ServeltXxxxxAware接口
a)返回的都是原生的对象

6.开启动态开发模式和动态方法的调用
2)配置文件struts-default.xml

默认为false


3)属性文件default.properties
4)调用动态方法规则
1)user!add(actin名字!方法名称)
2)官方不推荐使用(安全问题)
7.通配符

{2}.jsp
a)action的名字需要用来匹配 user_*_ user_add_ok
b)调用那个方法根据规则来走,从{1}开始的

8.默认的Action
1)用户在请求没有定义的aciton的时候就会调用默认的action
2)

ok.jsp

9.struts2标签
1)UI标签
a)表单里面的标签
2)逻辑标签
a)if else if else
3)迭代器标签
a)s:iterator
1)value:集合名称(ONGL表达式)
2)var:临时变量
4)数据展示标签
a)
1)value:要展示的数据(OGNL表达式)

5)日期
    a)<s:data>
        1)name:要展示的数据
        2)fomrat:格式化参数
      b)修改操作,显示时间时要三个标签嵌套
              <s:textfield label="生日" name="#request.user.birthday">
<s:param name="value">
   <s:date name="#request.user.birthday" format="yyyy-MM-dd"/>
</s:param>

10.OGNL
1)和EL表达式一样,但是要比EL强大很多
2)GONL:对象图导航语言,是一种功能强大的表达式语言.
OGNL表达式的计算是围绕OGNL上下文进行的。OGNL上下文实际上就是一个Map对象,由ognl.OgnlContext类表示,实现了java.utils.Map 的接口。它里面可以存放
很多个JavaBean对象。Struts框架默认就支持Ognl表达式语言。(从struts项目必须引入ognl.jar包可以看出)
3)符号
a)#:访问非根元素的时候要加#,不加访问的是跟元素
b)%:有时候strut2标签不认识OGNL,把表达式用%包起来,struts2就会当成OGNL解析
修改对象的表单里面,在展示数据用%把OGNL表达式包住
c)$:动态参数
4)说明:可以分为两类,一个根元素(放在值栈中),一个是非根元素(放在request,session,application中)
5)atrr:搜索attr(page–> request—>session–>applciation)

九大内置对象
1)page
2)pageContext
3)resquset
4)response
5)session
6)application
7)exception
8)out
9)config

11.类型转换
Struts2内默认转换器
表单中所有输入的值都将作为String类型提交到相应的Action,至于如何将这些String类型转换为Action中的属性的类型是需要做一些判断的,Struts2中默认有一个类型转换器,可以帮助我们完成大部分的自动转换操作。其支持的从String类型转换的目标类型如下:

● boolean和Boolean:字符串true会转换为布尔类型值true

● char和Character:字符串转字符

● int和Integer:字符串转整型类型

● long和Long:字符串转长整型

● float和Float:字符串转单精度浮点型

● double和Double:字符串转双精度浮点型

● Date:字符串转日期类型,需要字符串满足一定的格式

● 数组:多个input表单提交给同一个Action的属性,就会构成一个数组传入到该属性中

● 集合:和数组类似,需要指定了的类型,并且类型不能超出基本数据类型

对于我们在Action中声明的属性的类型,如果是以上的这些类型的话,那么从客户端提交的过来的字符串就可以默认使用该机制自动转换成对应的类型,完成自动赋值。否则就需要手动创建类型转换器来实现数据转换.

a)如何实现类型转换器
    1) 新建一个XxxTypeconvert类并继承StrutsTypeConverter
        a)convertFromString:把表单字符串转成对象(返回对象)(在给值栈赋值前调用)
        b)convertToString:把对象转成字符串 (返回要展示的值,字符串类型)(在给值栈赋值后,取值前调用)
    2)属性文件
        a)只对一个action起作用
            a)命名规则:ActionClassName-conversion.properties         
                                             ActionPoint-conversion.properties
            b)位置:和Action放在一起
            c)内容:point(Action的属性名)=类型转换器的全类名
                                                  point=com.qf.typeconvert.PointTypeconvert
        b)只要表单里面有point对象都起作用
            a)命名规则:xwork-conversion.properties
            b)位置:放在src下面
            c)内容:对象的全类名=类型转换器的全类名
                                                 com.qf.entity.Point=com.qf.typeconvert.PointTypeconvert
        3)如果局部类型转换和全局类型转换同时存在的话,局部类型转换具有较高的优先级,也就是以局部类型转换器为主。

12.编程式验证(校验)
1)action要继承ActionSupport
2)如何验证
a)在action类中复写validate方法
1)对象属性进行验证,通过调用this.addFieldError(“表单中的属性名称”,”错误信息”)添加错误信息
如果不写对应的属性名,就在验证失败后返回的页面添加显示所有错误信息
2)该方法对action中的所有方法都进行验证
b)写public void validateXxxx(方法名称)
1)只对某个方法进行校验
c)验证失败后默认返回值是input,所有要在配置文件中添加result
3)注意:每次验证失败并响应后,上一次请求就结束了

13.框架验证(校验)
1)继承ActionSupport
2)配置文件
a)命名:actionClassName-validation.xml
UserAction-validation.xml对整个action中的方法校验
actionClassName-actionName-validation.xml
UserAction-add-validation.xml对action中的add方法校验
b)位置:和action放在一起
c)如何去找框架提供的校验器的类型(default.xml)
d)通过调用校验器中的方法
e)结构
1)
a)
1)name:要和表单保持一致
a)field-validator
1)type:校验类型(去xwork-core-2.3.20.1.jar包中找/com/opensymphony/xwork2/validator/validators/default.xml)
a)可以调用方法(校验类型的jar包下的类的方法)
b)错误信息

14.拦截器
过滤器隶属于Web容器,可以过滤一切的请求(action,servlet,jsp,html…)
拦截器隶属于struts2框架,只能拦截action(jsp无法拦截)
过滤器内部采用回调函数来实现,拦截器采用动态代理来实现
1)自定义一个拦截器类
a)对整个action类所有方法进行拦截:继承AbstractInterceptor,复写里面的方法
b)对action类的某个方法进行拦截:继承MethodFilterInterceptor,复写里面的方法
1.1)方法
a)获取actionName: invocation.getInvocationContext().getName()
b)获取被拦截的方法(Method):invocation.getProxy().getMethod()
c)放行:返回invocation.invoke(),该方法的返回值是action的返回值
2)配置
2.1)在struts.xml里面定义一个拦截器
2.2)定义一个新的拦截器栈
a)引入默认的拦截器栈
b)引入自定义的拦截器
可以在自定义的拦截器中添加标签方法一,方法二,…拦截/放行某些方法
2.3)指向自定义的拦截器栈

16.国际化
1)Internationalization(简称i18n)
2)locale
a)方法
1)getAvailableLocales()获取本机支持的国家
2)Locale locale = new Locale(“en”, “US”); 改变当前语言环境
2)ResourceBundle
1)这个类可以实现国际化(java国际化)
ResourceBundle bundle = ResourceBundle.getBundle(“resources”,locale);根据基名和语言环境加载对应的语言资源文件
String name = bundle.getString(“key”);加载资源文件后, 程序就可以调用ResourceBundle实例对象的 getString方法获取指定的资源信息名称所对应的值。
2)属性文件(语言资源文件)
a)resources_en_US.properties
b)resources_zh_CN.properties
c)resources就是baseName
d)这两个属性文件中的key要保持一致
3)struts2实现国际化
1)aciton必须要继承ActionSupport
2)在struts.xml中要配置baseName(基明)

3)表单国际化
a)key:属性文件中的key
b)label:%{getText(‘key’)},底层调用后台getText()
label底层是用OGNL表达式调用后台getText()方法实现的
c)注意:表单提交按钮只能这样写
4)后台提示信国际化
a)getText(‘key’);
4)服务端是通过请求头信息中属性来判断的

17.解决表单重复提交(底层原理:令牌机制)
1)表单中要token标签
2)加一个token拦截器,不要忘了加默认的拦截器栈
3)框架校验到是重复提交后默认返回值invalid.token

这里写图片描述
这里写图片描述

18.上传
1)导包:commons-fileupload-1.3.1.jar,commons-io-2.2.jar
要有一个上传文件的表单
2)Action
a)file对象名称要和表单中的name属性保持一致
b)fileFileName:上传的文件名称(xxxxFileName) xxxx是Action中file对象的名称
c)file1ContentType:文件类型(xxxxContentType) 同上
3)文件上传限制




image/png,text/plain


1024000000



a)文件上传的拦截器fileUpload(struts-default.xml中)
1)类型:文件类型去tomcat的config下的web.xml里面去找,需要复制对应mime-type标签中的值过来
2)大小:单位是字节
b)提示信息struts-messages.properties(在struts2核心jar包下),可拓展到国际化提示
2).批量上传
1)把单个对象改成用数组去接受

19.下载
1.准备要下载的文件
2.把要下载的文件读成一个输入流,放在值栈中
3.在struts.xml中result要的type要配置成stream
a)inputName:指定输入流的名称 ins
b)contentDisposition:设置文件名称 attachment;filename=${fileName}

20.ajax和action交互
1)导入相关jar包
json-lib-2.3-jdk15.jar
ezmorph-1.0.6.jar
struts2-json-plugin-2.3.20.1.jar
commons-lang-2.4.jar
commons-logging-1.1.3.jar
commons-collections-3.1.jar
commons-beanutils-1.8.0.jar
2)定义一个action,造数据
3)配置文件
a)包继承json-defualt
1)json-defualt是插件提供的,它继承了struts-default包
b)result的type返回类型是json
c)需要指定要转换的数据(setRoot)


userList

21.全局异常处理
1)
a)exception-mapping
1)name:结果集的name
2)exception:异常的全类名
2)机制:抛出异常后先看有没有配置全局的异常处理,如果配了查看配置的异常是否是抛出异常的父类,如果是转发到指定页面,
如果不是就只直接显示异常信息。

22.OpenSessionInViewFilter
由于hibernate默认是懒加载(可以改,但会影响性能),但是数据在视图层展示时可能需要用到多次查询(如重新顾客信息后,往下加载页面用到了),若再次用到session时就不是之前的session对象了,因为事务提交时把session关闭了,会重新创建session
解决方法:加一个过滤器在一次请求并响应之后统一提交事务(注意:配置web.xml中过滤器时的顺序,要在最前面)
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
Transaction transaction = session.beginTransaction();
try {
chain.doFilter(request, response);
transaction.commit();
} catch (Exception e) {
e.printStackTrace();
transaction.rollback();
}
}

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值