Struts2总结
Struts1虽然可以很好的实现将控制与业务很好的分开,但其自身存在表象层单一(只支持jsp,不支持FrreMarker,Velocity),对Servlet API依赖,不利于代码重用(必须使用struts1中的类)。Struts2以webWork的设计为核心,吸收struts1的优点,使用拦截器来实现控制,不再依赖web容器,从而解决了对Servlet API的耦合,并且还对在其他框架下开发的程序提供了很好的兼容。
一、 action实现
1. 实现Action接口
2. 继承ActionSupport
3. 自定义Action
二、Struts2的配置文件
Constant元素用户配置常量,可以用来配置编码 <constant name=”” value=””/> <constant name=”struts.i18n.encoding” value=”utf-8”
Package元素定义包 <package name=”” namespace=”” extends=””> </package> Name:为必须的并且是唯一的,用来指定包的名称 Extends:类似Java的extends关键字,指定要扩展的包 Namespace:是一个可选属性,定义该包中的action命名空间,struts2会将请求的utl地址拆分namespace和action两个部分,框架首先在namespace中查找这个action,如何没找到就会在默认名称空间中查找。
法
Action元素映射工作单元 <action name=”” class=”” method=””> <result name=””>xxx.jsp</result> </action> Name:指定action的名称,用于匹配url地址,必须的,唯一的 Class:Action实现类的完整类型,不是必须的 Method:执行Action类时调用的方法,不是必须的,不写是默认execute方Convert:应用于action的类型转换的完整类名,不是必须的
Struts-default.xml文件是Struts2框架中默认配置文件,为框架提供了默认的设置,该配置文件会自动加载,struts-default包就来自这个文件。
Struts-plugin.xml文件是Struts2插件使用的配置文件,如何不是开发插件,则可以不编写这个配置文件。
三、result返回值
在action接口中,不仅提供了public void execute();方法,还提供了5个字符串类型的静态常量,作为常用的结果代码使用。每一个字符串名称都与struts.xml文件中的result结果视图名称相对应。
<result name=” SUCCESS” type=” Dispatcher”/> SUCCESS:程序正常处理,并返回给用户后的结果,默认。 NONE:程序正常处理,但不返回给用户任何提示
ERROR:处理任何结果失败
INPUT:需要更多用户输入才会执行
LOGN:用户正确登录后才能顺利执行
常用的结果集类型:
Dispatcher:默认,内部使用的是RequestDispatcher来转发请求 Redirect:内部使用的是HttpServletResponse的sendRedirect()来实现重定向,这就意味着请求中包含的参数,属性,action实例封装的属性将会丢失
RedirectAction:重定向到另一个action Chain:转发到另一个action
四、Action的作用
1.封装工作单元 可以把action看作控制器的一部分,其主要就是控制业务逻辑。每一个action类的方法都有一个具体的工作,都是一个工作单元。所以我们编写action应该尽量让业务逻辑纯粹和简洁。
2.数据转移场所 在action中定义的属性的值可在页面上使用,这会让action更加的简洁,并且可以使action于servlet API解耦。
3.返回结果字符串 Action根据业务逻辑执行的返回结果判断返回何种字符串,框架根据action返回的结果字符串选择对应的视图给用户
五、Action动态方法调用
1.开始动态方法配置 <constant name="struts.enable.DynamicMethodInvocation" value="true" />
2.动态方法调用
<action name="language*" class=" " method="{1}">
<result name="success">/index.jsp</result>
</action>
*:通配符,通配method方法
注:还有一种在url地址中的action名称后面用!方法名(!user!execute.action)来实现,不推荐使用。
六.传值
方式一:
1.
2. 在action中定义属性,并且定义setter,getter方法 在<input type=”text“ name=””/>中的name值和action定义的属
性名一致。
方式二:
1.
2. 在action中定义实体对象,并定义set胎儿,getter方法 在<input type=”text“ name=””/>中的name值要写action定义的
对象名.属性名(user.name)
方式三:
1. Action实现类要实现ModelDriven<User>接口
2. 定义User对象
3. 重写getMode()方法
Public User getModel(){
}
4. 在<input type=”text“ name=””/>中的name值要和User的属于名一致 User = new User(); Return user;
七、访问servlet API的方式
解耦和: 使用actioncontext类获取servlet API对象对应的map对象
ActionContext ac = actionContext.getContext(); Request: Map request = ac.get(); Session: Map session = ac.getSession(); Application: Map application = ac.getApplication(); 耦合:
直接访问Servlet API将使Action类于Servlet API耦合在一起。 使用ServletActionContext来直接获取Servlet API
八.struts2的ognl表达式
Ognl(object graph navigation language)是一种对象导航图语言,在框架中主要做表达式语言和类型转化器
表达式语言:在视图层将数据从页面传入框架和从框架中获取输出数据生成页面的过程
类型转换:页面中字符串类型转换和java类型直接的转换
框架在处理每个请求时,都会去创建该请求对应的运行环境,并将请求对应的action对象放入其中,action对象被放入在一个叫值栈(ValueStack)的对象中,vluestack对象是一个虚拟的对象,params会利用请求参数的名称作为ognl表达式,在值栈中找到目标属性。
值栈就是框架创建的一个存储区域,用来保存model对象,如果保存多个,会根据先后顺序压入值栈中,加入值栈中有多个对象具有相同的属性时,那么靠近值栈栈顶的优先级更高。
九、struts2的拦截器
ActionMapper:提供请求和action调用之间的映射,根据URL地址来查找是否存在对应的action调用的请求。
ActionMapping:保存了调用Action的映射信息,其中必须保存Action的命名空间信息和name属性。
ActionProxy:在XWork和真正的Action之间的充当代理,在执行Action的过程中,因为代理而非直接操作对象,所以可以在Action执行前后额外的操作,创建ActionInvocation对象。
ActionInvocation:表示Action的执行状态,它保存拦截器(按配置顺序),action实例。
Interceptor:连接器是一种可以在请求之前和之后执行的struts2组件,是struts2的重要特性,struts2框架的绝大数功能都是通过连接器来完成的。
拦截器在Action执行前后执行,有利于系统的解耦合,可以任意的组合Action提供复加优势。
拦截器的执行原理:围绕Action和result的执行而执行,以链式执行,遵循先进后出的规则,任何一个连接器都可以直接返回,从而终止余下的拦截器。执行的最后一个连接器会执行invoke()方法会执行action。
连接器有三个阶段的,有条件的执行周期:
1. 做一些Action执行前的预处理,可以准备,过滤,改变或者操作任何可以访问的数据,包括Action。
2. 调用ActionInvocation的invoke()方法将控制转交给后续的拦截器或者返会字符串终止执行,也可以不调用invoke()方法,直接返回字符串。
3. 做一些Action执行后的处理,此时拦截器可以改变访问的对象和数据,只是已经选择了一个结果程序给用户。
拦截器的配置:
1.
2. 通过<interceptor/>元素来定义拦截器 通过<interceptor-ref/>元素类使用拦截器
<interceptors>
<interceptor name=”interName” class=””/>
</interceptor>
<action>
<interceptor-ref name=”interName”/> </action>
4配置拦截器栈配置:
<interceptors> <!—定义拦截器--> <interceptor name=”” class=””/> <!—定义拦截器栈--> <interceptor-stack name=”permissionStack”> <!—指引定义的拦截器--> <interceptor-ref name=””/> <!—使用系统拦截器--> <interceptor-ref name=”defaultStack”/> </interceptor-stack> </interceptors>
<action>
<!—引用拦截器栈--> <interceptor-ref name=””/> </action>
Struts2内置拦截器:
Params:将请求中的数据设置到Action中 Staticparams:将在配置文件中通过Action元素的子元素param设置的参
数设置到对应的Action中。
ServletConfig:提供一种源于servlet API的各种对象注入Action当中的简洁方法,Action必须实现相应的接口,才能注入。
FileUpload:将文件和元数据从多重请求转换为常规的请求数据,以便能将它们设置在对应的Action。
Validation:用于执行数据校验。 Workflow:提供当数据校验错误时终止流程的功能。 Exception:捕获异常,并且能够根据类型将捕获的异常映射到用户自定义的错误页面。
自定义拦截器:
1.
2. 实现Interceptor接口 继承abstractInterceptor类
都可以实现自定义拦截器的。
提供了3个方法: Void init():在该拦截器初始化之后,在该拦截器执行之前,系统回调。 Void destroy():在该拦截器实例被销毁之前,系统回调。 String interceptor():实现拦截器功能。
十、OGNL表达式:
Object graph navigation language,对象导航图语言,主要做表达式语言和类型转换器。
1. 表达式语言:从视图传入数据到框架或从框架获取数据到视图,在输入时,数据从请求参数转移到Action的javabean属性上。
2. 数据转换器:页面中字符串类型的数据和Java数据类型之间都会发生
转换。
Params拦截器会利用请求参数的名字作为ognl表达式,在值栈上找到目标属性。 valueStack:值栈就是框创建的一个存储区域,用来保护model对象,它具有栈的特性,可以存放多个,但会按照先后顺序压入栈低,越靠近栈底的对象优先级更高。
在基于HTTP协议的web应用中,客户端请求的所以内容均都以文本编码的方法传输到服务器,所在需要数据类型转换。
Ognl表达式在访问ActionContext中的数据时,在加 # 号。
十一、国际化:
1. 在struts.xml文件中指定资源文件的基名及存储路径。‘
<constant
value=”message”/>
2.按照需求创建对应的词源文件,用来存放相应的词源 Message.en.properties name=”struts.custom.i18n.resources” 3.实现jsp页面的信息的国际化显示 <s:text name=”name”/>
十二、struts2的ajax
第二篇:struts2常见错误总结
struts2常见错误总结
1.Caught exception while loading file struts-default.xml -
[unknown location]
解决办法:
由于lib包冲突造成的,将两个解析xml用的jar从项目里移到tomacat的lib下面就ok了,xml-apis.jar xerces-2.6.2.jar
2.严重: Exception starting filter struts2
Error building results for action login in namespace - action - file:/E:/apache-tomcat-6.0.14/webapps/testStruts2/WEB-INF/classes/struts.xml57
原因:在web.xml已声明使用模板,并对所有的类进行了监听,但在处理过程中,发现不知道到哪里去找模板的配置文件,即在struts.xml中已使用了模板,但并没有告诉程序应该到哪去解析这些内容,即titles-default.java文件应该声明出来,
原因1:在struts.xml中错误的声明如下:
<package name="aa1" extends="struts-default" >
<action name="login" class="com.sun.demo.LoginAction">
<result type="tiles">showWelcomePage</result>
</action>
</package>
应改为:
<package name="aa1" extends="titles-default" >
<action name="login" class="com.sun.demo.LoginAction">
<result type="tiles">showWelcomePage</result>
</action>
</package>
原因2:titles.xml文件的 错误配置
<tiles-definitions>
<definition name="showWelcomePage" template="template.jsp"> <put-attribute name="menu" >menu_1.jsp</put-attribute> <put-attribute name="content" >login_form.jsp</put-attribute>
</definition>
正确的配置为:
<tiles-definitions>
<definition name="showWelcomePage" template="template.jsp">
<put-attribute name="menu" value="/menu_1.jsp"></put-attribute> <put-attribute name="content" value="/login_form.jsp"></put-attribute>
</definition>
页面显示情况如下:
错误配置如下:
<definition name="showWelcomePage" template="template.jsp">
<put-attribute name="menu" value="menu_1.jsp"></put-attribute> <put-attribute name="content" value="login_form.jsp"></put-attribute>
</definition>
正确配置如下 :
<definition name="showWelcomePage" template="template.jsp">
<put-attribute name="menu" value="/menu_1.jsp"></put-attribute> <put-attribute name="content" value="/login_form.jsp"></put-attribute>
</definition>
在value属性中,以"/"开头表示地址,如果不以“/”开头,则系统会默认为内容
3.执行增加操作时,直接对对象进行操作,对象中各字段值都正确,但插入数据库后乱码
解决办法(1)统一页面和数据库编码为utf-8
(2)修改hibernate的配置文件,修改url属性为:
jdbc:mysql:/127.0.0.1:3306/shop?useunicode=true&characterEncuoding=utf-8
4.could not create Query
原因:sql语句书写不正确
5.mysql数据库问题
mysql Error 1115号错误,utf编码
解决办法:
安装时编码采用默认的编码,安装成功后,再到安装路径下修改安装语言,修改mysql/my.ini文件。
6.在对对象进行删除操作时,如果对象中的某个字段不允许为空,则必须赋值,否则会提示:字段名not null等信息
7.在进行页面跳转时(从action中到页面,使用了模板),提示I/O异常
解决办法:tiles.xml文件中document题头没有书写正确
8.在进行页面跳转时,已经跳转到了相应的页面,但显示结果页面不正确。
解决办法:检查模板中的各个属性是否正确配置,尤其注意有的属性会忘记配置。
9.对日期类型数据进行操作
(1)配置文件中相对应的字段属性改为date
(2)pojo类中引用java.sql.date
10.Nosuchdefinition titles...
原因:tiles.xml文件中的配置有问题,尤其注意name属性
11.在服务器一启动,就会报“Filter error”等提示信息,项目无法建立
原因1)struts.xml配置错误
1>package中extends错误
2>action中
12、No result defined for action ***Action and result success
这个错误产生的原因是,在struts.xml中配置没有配置success result。我的理解是action执行完后,必须产生一个result类。这个类可是servlet或是其他,但不能为空。 解决方法:增加result success定义。
<result>***.jsp</result>
13、No result defined for action ***Action and result input 这个错误,在提交数据时经常碰到。定义的struts2 intercept发挥了作用,当POJO类型与输入的类型不同时,intercept类会中止拦截,并返回输入页面。详细的错误可在使用<s:fielderror/>来获取。
解决方法:增加resut input定义。
<result name="input">***.jsp</result>
14、There is no Action mapped for namespace / and action name ***Action
可以直译为没有找到这个action,也就是说在struts.xml中没有定义这个action。这个错误一般是action的名字拼写错误造成的,请仔细检查struts.xml的定义与页面的acrion是否一致。
15、Class ognl.OgnlRuntime can not access a member of class ***Action with modifiers "private"
关键字是"private",action类中的字段为private,这样页面(如jsp)是无法访问到的,这也是struts2面向对象的一大特征。
解决方法:
在action中添加set get方法,这样struts会自访问这个方法。set get方法必须遵循bean的标准写法。
16、Exception starting filter struts2
未定变义struts-default。也package中加入extends="struts-default"
17、笔下之前遇到一个问题:报:Error building results for action admin_* in namespace
同时还报:Caused by: There is no result type defined for type 'redirectAction'
网上说是package元素里要加入extends="struts-default"属性,
但是package元素里有extends="struts-default"属性,之前很费解
最后修改redirectAction为redirect-action解决问题,个人估计是struts2版本的问题
<result name="checkSuccess" type="redirect-action">
总结:仔细看错误原因很重要,对症下药!
18、redirect和redirect-action的区别
使用redirect需要后缀名
使用redirect-action"不需要后缀名
<result name="success" type="redirect">viewTask.action</result>
<result name="success" type="redirect-action">viewTask</result>