Struts2学习

Struts2是在WebWork2基础发展而来。

Struts2相对Struts1优点:

1 Struts2属于无侵入式设计

2 Struts2提供了拦截器,利用拦截器可以进行AOP编程,实现如权限拦截、事务控制等功能

3 Struts2提供了类型转换器,可以把特殊的请求参数转换成指定类型。相同功能Struts1需要底层实现BeanUtil注册类型转换器

4 Struts2提供支持多种表现层技术,如:JSP、FreeMaker、Velocity等

5 Struts2的输入校验可以对指定方法进行校验

6 提供了全局范围、包范围和Action范围的国际化资源文件管理实现

 

Struts2 jar包功能:

struts2-core-xx.jar:struts2核心类库

xwork-xx.jar:XWORK类库,Struts2基础

ognl-xx.jar:对象图导航语言,struts2框架通过其读写对象的属性

freemarker-xx.jar:Struts2的UI标签的模板使用FreeMarker边写

commons-logging-xx.jar:Struts2框架用来支持Log4J和JDK的日志记录

commons-fileupload-xx.jar:文件上传组件

 

web.xml 过滤器配置:

org.apache.struts2.dispatcher.FilterDispatcher 2.1.3之前版本

org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter 2.1.3之后版本

<filter>
       <filter-name>struts2</filter-name>

<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
      <filter-name>struts2</filter-name>
     <url-pattern>*.action</url-pattern>

 </filter-mapping>

 

struts.xml配置

struts2读取struts.xml内容后,以Javabean形式存放内存

<struts>
   <package name="p" namespace="/test" extends="struts-default">
        <action name="helloworld" class="HelloWorldAction" method="execute" >
            <result name="success">/WEB-INF/page/hello.jsp</result>
        </action>
    </package> 
</struts>

Struts2 把各种 action 分门别类地组织成不同的包. 可以把包想象为一个模块. 一个典型的 struts.xml 文件可以有一个或多个包

每个 package 元素都必须有一个 name 属性. 该 name 属性可被其它 package 引用

namespace 属性是可选的, 如果它没有给出, 则以 “/” 为默认值. 若 namespace 有一个非默认值, 则要想调用这个包里的Action, 就必须把这个属性所定义的命名空间添加到有关的 URI 字符串里

Struts2很多核心功能都是拦截器实现的,struts2每个package都应该继承struts-default。对请求参数封装到action、文件上传和数据验证等等都是拦截器实现的,struts-default定义了拦截器和result类型

package 通过abstract="true"定义为抽象包,抽象包不能包含action

 

Action名称的搜索顺序:

例如:http://server/struts2/path1/path2/path3/test.action

1 首先寻找namespace为/path1/path2/path3的package,如果不存在此package进入步骤2;若存在则在当前package中寻找test.action,若找不到进入默认package寻找test.action,若找不到action则404

2 首先寻找namespace为/path1/path2的package,如果不存在此package进入步骤3;若存在则在当前package中寻找test.action,若找不到进入默认package寻找test.action,若找不到action则404

3 首先寻找namespace为/path1的package,如果不存在此package进入步骤2;若存在则在当前package中寻找test.action,若找不到进入默认package寻找test.action,若找不到action则404

4 首先寻找namespace为/的package,如果不存在此package进入步骤2;若存在则在当前package中寻找test.action,若找不到进入默认package寻找test.action,若找不到action则404

注:默认package name为空字符串

Action名称搜索流程图


struts2.xml默认值:

1 若<action>没有指定class 默认是ActionSupport

2 若action没有指定method,默认执行execute()方法

3 若没有指定result name,默认值success

4 若没有指定result type,默认值dispacher

 

Action的result的转发类型:

action方法返回String对应result的name,struts2根据这个值决定响应结果。

result主要属性:

name:结果的名字,与Action方法返回值相匹配,默认值success

type:响应结果的类型,默认值dispatcher

在result中还可以使用${属性名}表达式访问action中的属性,表达式里属性名对应action中的属性。

<action name="helloword" class="com.HelloWorldAction">
            <result type="redirect">/view.jsp?id=${id}</result>
 </action>

重定向action在别的命名空间:

<result type="redirectAction">
                <param name="actionName">helloword</param>
                <param name="namespace">/test</param>
</result>

plaintext显示原始文件内容:

<result name="source" type="plainText">
                <param name="location">/xx.jsp</param>//路径
                <param name="charSet">UTF-8</param>//读取文件编码
</result>

结果类型: dispatcher

最常用的结果类型,struts2默认结果类型;该结果类型有一个location参数,location是一个默认参数;把控制权转发给应用程序里的指定资源;dispatcher不能把控制权转发给一个外部资源。redirect可以重定向外部资源。

结果类型:redirect

把响应重定向到另一个资源。

参数:

location:用来给出重定向的目的地。默认属性

parse:用来表明是否把location参数的值视为一个OGNL表达式来解释,默认值为false

结果类型:redirectAction

把响应重定向到另一个 Action

参数:

actionName: 指定 “目的地” action 的名字. 它是默认属性

namespace: 用来指定 “目的地” action 的命名空间. 如果没有配置该参数, Struts 会把当前 Action 所在的命名空间作为 “目的地” 的命名空间

结果类型:chain

基本用途是构成一个 action 链: 前一个 action 把控制权转发给后一个 action, 而前一个 action 的状态在后一个 action 中依然保持

参数:

actionName: 指定目标 action 的名字. 它是默认属性

namespace: 用来指定 “目的地” action 的命名空间. 如果没有配置该参数, Struts 会把当前 action 所在的命名空间作为 “目的地” 的命名空间

method: 指定目标 action 方法. 默认值为 execute

 

action属性注入:

Struts2为Action中的属性提供了依赖注入功能,在struts2的配置文件中,可以很方便地为Action中的属性注入值。

public class HelloWorldAction{
    private String savePath;
    public String getSavePath() {
        return savePath;
    }
    public void setSavePath(String savePath) {
        this.savePath = savePath;
    }
}
<action name="helloworld" class="cn.action.HelloWorldAction" >
        <param name="savePath">/images</param>
        <result name="success">/hello.jsp</result>
</action>


 

struts2常量设置:

struts.i18n.encoding:指定Web应用的默认编码集,相当于调用 HttpServletRequest的setCharacterEncoding方法

struts.action.extension:指定需要Struts 2处理的请求后缀,该属性的默认值是action

struts.serve.static.browserCache:设 置浏览器是否缓存静态内容,默认值为true

struts.configuration.xml.reload:当 struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false

struts.devMode:开 发模式下使用,这样可以打印出更详细的错误信息 

struts.ui.theme:默 认的视图主题

struts.objectFactory:该 属性指定Struts 2中的action由Spring容器创 建

struts.serve.static.browserCache:该属性设置浏览器是否缓存静态内容。当应用处于开发阶段时,我们希望每次请求都获得服务器的最新响应,则可设置该属性为false。

struts.enable.DynamicMethodInvocation:该属性设置Struts 2是否支持动态方法调用,该属性的默认值是true。如果需要关闭动态方法调用,则可设置该属性为false。

struts.enable.SlashesInActionNames:该属性设置Struts 2是否允许在Action名中使用斜线,该属性的默认值是false。如果开发者希望允许在Action名中使用斜线,则可设置该属性为true。

struts.tag.altSyntax:该属性指定是否允许在Struts 2标签中使用表达式语法,因为通常都需要在标签中使用表达式语法,故此属性应该设置为true,该属性的默认值是true。

struts.i18n.reload:该属性设置是否每次HTTP请求到达时,系统都重新加载资源文件。该属性默认值是false。

struts.ui.templateDir:该属性指定视图主题所需要模板文件的位置,该属性的默认值是template,即默认加载template路径下的模板文件。

struts.ui.templateSuffix:该属性指定模板文件的后缀,该属性的默认属性值是ftl。该属性还允许使用ftl、vm或jsp,分别对应FreeMarker、 Velocity和JSP模板。

struts.configuration.xml.reload:该属性设置当struts.xml文件改变后,系统是否自动重新加载该文件。该属性的默认值是false。

struts.velocity.configfile:该属性指定Velocity框架所需的velocity.properties文件的位置。该属性的默认值为 velocity.properties。

struts.velocity.contexts:该属性指定Velocity框架的Context位置,如果该框架有多个Context,则多个Context之间以英文逗号(,)隔开。

struts.velocity.toolboxlocation:该属性指定Velocity框架的toolbox的位置。

struts.url.http.port:该属性指定Web应用所在的监听端口。该属性通常没有太大的用户,只是当Struts 2需要生成URL时(例如Url标签),该属性才提供Web应用的默认端口。

     struts.url.https.port

    该属性类似于struts.url.http.port属性的作用,区别是该属性指定的是Web应用的加密服务端口。

struts.url.includeParams

该属性指定Struts 2生成URL时是否包含请求参数。该属性接受none、get和all三个属性值,分别对应于不包含、仅包含GET类型请求参数和包含全部请求参数。


struts.custom.i18n.resources

该属性指定Struts 2应用所需要的国际化资源文件,如果有多份国际化资源文件,则多个资源文件的文件名以英文逗号(,)隔开。


struts.dispatcher.parametersWorkaround

对于某些Java EE服务器,不支持HttpServlet Request调用getParameterMap()方法,此时可以设置该属性值为true来解决该问题。该属性的默认值是false。对于 WebLogic、Orion和OC4J服务器,通常应该设置该属性为true。

struts.freemarker.manager.classname

该属性指定Struts 2使用的FreeMarker管理器。该属性的默认值是org.apache.struts2.views.freemarker.FreemarkerManager,这是 Struts 2内建的FreeMarker管理器。

struts.freemarker.wrapper.altMap

该属性只支持true和false两个属性值,默认值是true。通常无需修改该属性值。

struts.xslt.nocache

该属性指定XSLT Result是否使用样式表缓存。当应用处于开发阶段时,该属性通常被设置为true;当应用处于产品使用阶段时,该属性通常被设置为false。

struts.configuration.files

该属性指定Struts 2框架默认加载的配置文件,如果需要指定默认加载多个配置文件,则多个配置文件的文件名之间以英文逗号(,)隔开。该属性的默认值为struts- default.xml,struts-plugin.xml,struts.xml,看到该属性值,读者应该明白为什么Struts 2框架默认加载struts.xml文件了。

 

struts2处理流程:

struts2多个配置文件指定:

在struts.xml可以通过include标签进行多个配置文件包含

<include file=""/>

 

struts2动态方法调用

方法一(动态方法):struts.enable.DynamicMethodInvocation:true和helloworld.action!other.action结合使用

方法二(通配符):<action name="helloworld_*" class="HelloWorldAction" method="{1}"></action>

通配符映射规则:

若找到多个匹配, 没有通配符的那个将胜出

若指定的动作不存在, Struts 将会尝试把这个 URI 与任何一个包含着通配符 * 的动作名及进行匹配    

被通配符匹配到的 URI 字符串的子串可以用 {1}, {2} 来引用. {1} 匹配第一个子串, {2} 匹配第二个子串…

{0} 匹配整个 URI

若 Struts 找到的带有通配符的匹配不止一个, 则按先后顺序进行匹配

* 可以匹配零个或多个字符, 但不包括 / 字符. 如果想把 / 字符包括在内, 需要使用 **. 如果需要对某个字符进行转义, 需要使用 \.

 

struts2接受请求参数:

1 struts2能自动接受请求参数并赋予给同名属性。

2 对于复合类型,通过反色结束调用默认构造方法创建对象,然后通过反射技术调用同名的属性的setter方法来获取请求参数值。

 

struts类型转换器:

public class DateTypeConverter extends DefaultTypeConverter{

        public Object convertValue(Map context,Object value,Class toType){

               SimpleDateFormat dataFormat=new SimpleDateFormat("yyyyMMdd");

               try{    

                     if(toType==Date.class){

                              String[] params=(String[])value;return dateFormat.parse(params[0]);

                      }else{

                               Date date=(Date)value;return dateFormat.format(date);

                      }

                }catch(Exception e){}

        }

}

1 局部类型转换器HelloWorldAction-conversion.properties放置action类所在包下

birthday=converter.DateTypeConverter

2 全局类型转换器xwork-conversion.properties放置src路径下

java.util.Date=converter.DateTypeConverter

 

访问或添加request/session/application属性

request属性设置:ServletActionContext.getRequest().setAttribute

session属性设置:ServletActionContext.getRequest().getSession().setAttribute

application属性设置:ServletActionContext.getContext().put

JSP获取:${requestScope.req}${sessionScope.ses}${applicationScope.app}    默认是requestScope作用域

 

文件上传:

1 commons-fileupload.jar、commons-io.jar加入

2 File uploadImage;//得到上传文件 String uploadImageContentType;//文件类型 String uploadImageFileName;//文件名称

多文件上传:

File[] uploadImages;//得到上传文件 String[] uploadImageContentTypes;//文件类型 String[] uploadImageFileNames;//文件名称

 

自定义拦截器:

public class MyInterceptor implements Interceptor{

public void destroy(){}

public void init(){}

public String intercept(ActionInvocation invocation ) throws Exception{

return invocation.invoke();

}

}

struts.xml配置:

<interceptors><interceptor name="permission" class="MyInterceptor"/></interceptors>

<action><interceptor-ref name="defaultStack"/><interceptor-ref name="permission"/></action>

<interceptor-ref name="defaultStack"/>是struts-default默认的拦截器

 

struts2 action所有方法进行输入校验:

1 通过重写validate()方法,对execute方法签名的方法验证

2 通过validateXxx()方法对xxx方法进行校验

流程:

1 类型转换对请求参数进行类型转换并且复制给action的属性

2 如果转换出现异常,异常信息保存在ActionContext,conversionError拦截器将异常添加到fieldErrors里。不管类型转换是否出现异常,都会进入3

3 反射技术调用validateXxx 

4 再调用validate方法

5 fieldErrors.size大于0,请求将转发至名称为input的视图,若没有错误信息,系统将执行xxx方法

基于XML方式进行action方法验证:

ActionName同一个包下:ActionClassName-validate.xml

<validators>

<field name="username">

<field-validator type="requiredstring">

<param name="trim">true</param>

<message>用户名不能为空!</message>

</field>

</validators>

<field>指定要校验属性,<field-validator>指定校验器requiredstring系统提供com.opensymphony.xwork2.validators下的default.xml中定义了

message指定校验错误后的失败信息,国际化可以指定key属性  trim是String trim作用

指定方法:ActionClassName-ActionName-validate.xml

 

国际化:

baseName_language_country.properties

<constant name="struts.custom.i18n.resources" value="baseName"/>

<s:text name="pkey1"/>

包范围国际化:

在java的包下放package_language_country.properties

处于该包和子包下的action都可以访问该资源,当key找不到的时候会从struts.custom.i18n.resources中找

类范围国际化:

ActionClassName_language_country.properties

类同包下,若找不到,则找package,再找不到就找struts.custom.i18n.resources指定文件

 

OGNL:

若希望访问栈中ContextMap中的数据,需要给OGNL表达式加上一个前缀字符#,若没有,搜索将在ObjectStack里进行

property标签:

用来输出值栈中的一个属性值

default:默认值 escape:是否对HTML转义 value:值

ObjectStack对象属性访问:

object.propertyName object['propertyName'] object["propertyName"]

ObjectStack对象可以通过从开始的下标来引用

[0].propertyName [n]:从第n个开始搜索,而不是只搜索第n个对象,若从栈顶对象开始搜索,则可以省略下标部分

 

ContextMap属性值#object.propertyName

session code属性 #session.code

request customer属性的name属性值:#request.customer.name

返回域对象按request,session.application的顺序的属性lastAccessDate #attr.lastAccessDate

调用字段和方法:

@fullyQualifiedClassName@fieldName:

@fullyQualifiedClassName@methodName(argumentList): 

调用一个实例字段或方法的语法, 其中 object 是 Object Stack 栈里的某个对象的引用:

.object.fieldName: [0].datePattern

.object.methodName(argumentList): [0].repeat(3, “Hello”);

 

 

EL表达式:

${fieldName} 原理: Struts2 将包装 HttpServletRequest 对象后的 org.apache.struts2.dispatcher.StrutsRequestWrapper 对象传到页面上, 而这个类重写了 getAttribute() 方法.  

异常处理: exception-mapping 元素:

exception-mapping 元素: 配置当前 action 的声明式异常处理 exception-mapping 元素中有 2 个属性

exception: 指定需要捕获的的异常类型。异常的全类名

result: 指定一个响应结果, 该结果将在捕获到指定异常时被执行, 既可以来自当前 action 的声明, 也可以来自 global-results 声明. 可以通过 global-exception-mappings 元素为应用程序提供一个全局性的异常捕获映射. 但在 global-exception-mappings 元素下声明的任何 exception-mapping 元素只能引用在 global-results 元素下声明的某个 result 元素 声明式异常处理机制由  ExceptionMappingInterceptor 拦截器负责处理, 当某个 exception-mapping 元素声明的异常被捕获到时, ExceptionMappingInterceptor 拦截器就会向 ValueStack 中添加两个对象:

exception: 表示被捕获异常的 Exception 对象

exceptionStack: 包含着被捕获异常的栈

可以在视图上通过 <s:property> 标签显示异常消息

 

Struts2 运行流程分析

1. 请求发送给 StrutsPrepareAndExecuteFilter

2. StrutsPrepareAndExecuteFilter 询问 ActionMapper: 该请求是否是一个 Struts2 请求(即是否返回一个非空的 ActionMapping 对象)

3. 若 ActionMapper 认为该请求是一个 Struts2 请求,则 StrutsPrepareAndExecuteFilter 把请求的处理交给 ActionProxy 4. ActionProxy 通过 Configuration Manager 询问框架的配置文件,确定需要调用的 Action 类及 Action 方法

5. ActionProxy 创建一个 ActionInvocation 的实例,并进行初始化

6. ActionInvocation 实例在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。

7. Action 执行完毕,ActionInvocation 负责根据 struts.xml 中的配置找到对应的返回结果。调用结果的 execute 方法,渲染结果。在渲染的过程中可以使用Struts2 框架中的标签。

8. 执行各个拦截器 invocation.invoke() 之后的代码

9. 把结果发送到客户端

 

Action 配置相关的 Annotation:

Action 配置相关的 Annotation

@Action 主要用于修饰 Action 类里的方法, 用于将方法映射为指定的 URL.

 可以指定一个 value 属性, 用于指定该 Action 映射的URL(类似于在 struts.xml 文件中配置该 Action 时为 <action /> 元素指定的 name 属性值)

还可以指定一个 param 属性, 该属性是一个字符串数组, 用于该 Action 指定参数名和参数值. params 属性值应该遵守如下格式: {“name1”, “value1”, “name2”, “value2”, …}. 该属性用于为该 Action 注入属性值

@Actions 也用于修饰 Action 类里的方法, 用于将该方法映射到多个 URL. @Actions 用于组织多个 @Action

和 Result 配置相关的 3 个 Annotation 是 @Result , @Results 和 @ResultPath @Results 用于组织多个 @Result, 因此它只需一个 value 属性值, 该 value 属性值为多个 @Result。

包和命名空间相关的 Annotation:

@Namespace: 修改 Action. 该 Annotation 只需指定一个 value 属性值, 用于指定被修改的 Action 所在的命名空间.

@ Namespaces: 修饰 Action. 用于组合多个 @Namespace.

拦截器配置相关的 Annotation 有 @InterceptorRef, @InterceptorRefs, @DefaultInterceptorRef @InterceptorRefs 用于指定多个 @InterceptorRef, 因此该 Annotation 只需指定一个 value 属性值, 该 value 属性值为多个 @ InterceptorRef @InterceptorRef 用于为指定 Action 引用拦截器或者拦截器栈. 也就是 struts.xml 文件中 <action…> 节点内部的 <interceptor-ref …/> 子元素的作用. 属性如下 vlaue*: 用于指定所引用拦截器或拦截器栈的名字, 相当于 <interceptor-ref …/> 子元素中的 name 属性 params: 用于覆盖所引用该拦截器的默认参数值. 该属性应满足 {name1, value1, name2, value2, …} 的格式. 相当于 <interceptor-ref …/> 元素的 <param> 子元素. @InterceptorRef 有如下两种用法 Action 级的拦截器配置 方法级的拦截器配置 @DefaultInterceptorRef: 主要用于修饰包, 用于指定该包的默认拦截器. 这个 Annotation 只有一个 value 属性, 用于指定默认拦截器的名字.

 

与spring整合流程:

1 struts2-spring-plugin-2.2.1.jar

2 在 Spring 的配置文件中配置 Struts2 的 Action 实例

3 在 Struts 配置文件中配置 action, 但其 class 属性不再指向该 Action 的实现类, 而是指向 Spring 容器中 Action 实例的 ID

自动装配:

利用  Spring 插件的自动装配功能, 当 Spring 插件创建 Action 实例后, 立即将 Spring 容器中对应的业务逻辑组件注入 Action 实例. 配置自动装配策略: Spring 插件的自动装配可以通过 

struts.objectFactory.spring.autoWire 常量指定

name: 根据属性名自动装配.

type: 根据类型自动装配. 若有多个 type 相同的 Bean, 就抛出一个致命异常; 若没有匹配的 Bean, 则什么都不会发生, 属性不会被设置

auto: Spring 插件会自动检测需要使用哪种方式自动装配方式

constructor: 同 type 类似, 区别是 constructor 使用构造器来构造注入所需的参数

整合流程: 安装 Spring 插件 正常编写 struts 配置文件 编写 spring 配置文件, 在该配置文件中不需要配置 Action 实例

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流光影下

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值