Struts2知识点总结

Struts 2的基本流程

 Struts 2框架由3个部分组成:核心控制器FilterDispatcher、业务控制器用户实现的业务逻辑组件。在这3个部分里,Struts 2框架提供了核心控制器FilterDispatcher,而用户需要实现业务控制器和业务逻辑组件。

2.核心控制器:FilterDispatcher

 FilterDispatcher是Struts 2框架的核心控制器,该控制器作为一个Filter运行在Web应用中,它负责拦截所有的用户请求,当用户请求到达时,该Filter会过滤用户请求。如果用户请求以action结尾,该请求将被转入Struts 2框架处理。

Struts 2框架获得了*.action请求后,将根据*.action请求的前面部分决定调用哪个业务逻辑组件,例如,对于login.action请求,Struts 2调用名为login的Action来处理该请求。

Struts 2应用中的Action都被定义在struts.xml文件中,在该文件中定义Action时,定义了该Action的name属性和class属性,其中name属性决定了该Action处理哪个用户请求,而class属性决定了该Action的实现类。

Struts 2用于处理用户请求的Action实例,并不是用户实现的业务控制器,而是Action代理——因为用户实现的业务控制器并没有与Servlet API耦合,显然无法处理用户请求。而Struts 2框架提供了系列拦截器,该系列拦截器负责将HttpServletRequest请求中的请求参数解析出来,传入到Action中,并回调Action 的execute方法来处理用户请求。

显然,上面的处理过程是典型的AOP(面向切面编程)处理方式。图3.19显示了这种处理模型。

 

图3.19  Struts 2的拦截器和Action

从图3.19中可以看出,用户实现的Action类仅仅是Struts 2的Action代理的代理目标。用户实现的业务控制器(Action)则包含了对用户请求的处理。用户的请求数据包含在HttpServletRequest对象里,而用户的Action类无需访问HttpServletRequest对象。拦截器负责将 HttpServletRequest里的请求数据解析出来,并传给业务逻辑组件Action实例。

3.业务控制器

  正如从图3.19所看到的,业务控制器组件就是用户实现Action类的实例,Action类里通常包含了一个execute方法,该方法返回一个字符串——该字符串就是一个逻辑视图名,当业务控制器处理完用户请求后,根据处理结果不同,execute方法返回不同字符串   ——每个字符串对应一个视图名。

程序员开发出系统所需要的业务控制器后,还需要配置Struts 2的Action,即需要配置Action的如下三个部分定义:

—  Action所处理的URL。

—  Action组件所对应的实现类。

—  Action里包含的逻辑视图和物理资源之间的对应关系。

每个Action都要处理一个用户请求,而用户请求总是包含了指定URL。当Filter Dispatcher拦截到用户请求后,根据请求的URL和Action处理URL之间的对应关系来处理转发。

 

 

 

 

 

 

 

 

 

在action元素的name属性中可以使用*通配符,它可以匹配除了/以外的多个连续字符,在action元素的class和method属性以及result元素中可以引用*通配符在访问期间实际匹配的内容,例如:

方式1:

<action name="view6*" class="cn.itcast.struts2demo.HelloWorldAction"method="{1}">

       <result>/WEB-INF/page/{1}.jsp</result>

</action>

方式2:

<action name="view7_*"class="cn.itcast.struts2demo.HelloWorldAction"method="{1}">

       <result>/WEB-INF/page/{1}.jsp</result>

</action>

如果*匹配的内容为空,则调用execute方法;对于采用下划线连接*的方式,如果访问路径中没有为*部分指定内容,那么在访问路径中还可以省略下划线。

使用*通配符可能导致有多个action元素与一个访问路径匹配,这时候以排在配置文件中最后的配置项为准,所以更具体的模式应在更不具体的模式之后进行配置。

请描述<actionname=“*”><result>/WEB-INF/{1}.jsp</result></action>的含义。

 

 

 

 

 

 

struts2的配置文件

配置文件可以分为三部分:

1.web.xml用于配置FilterDispatcher

<filter>

<filter-name>action2</filter-name>

<filter-class>

org.apache.struts2.dispatcher.FilterDispatcher

</filter-class>

</filter>

<filter-mapping>

<filter-name>action2</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

 

 

 

 

2.struts.properties配置web应用程序的执行环境

该配置文件了一种改变框架默认行为的途径,通常你不需要去修改它。这个文件中包含的所有属性都可以在web.xml中的init-param中进行配置,或者在struts.xml中用constant标签进行配置。有关这个文件配置项的最新信息可以见http://struts.apache.org/2.x/docs/strutsproperties.html.

默认的配置文件为default.properties被包含在struts2的核心jar包中发布。为了修改这个默认的文件配置,你可以在你工程的classpath中加入一个struts.properties文件在其中添加配置项,那么就会覆盖默认配置文件的设置。

有如下一些配置项可能被常用:

struts.i18n.reload = true – 使能重新加载国际化文件

struts.devMode = true – 设置为开发模式便于输出更多便于理解的调试信息

struts.configuration.xml.reload = true – 当改变Action的配置时能够自动重新加载配置,而不用重启整个服务器

struts.url.http.port = 8080 – 设置服务器的工作端口,保证自动生成的url是正确的。

 

 

 

 

 

 

3.struts.xml配置web应用程序中的组件

struts.xml可以从应用中完全移除,其中的配置项可以通常别的方法去完成设置。例如方法的annotation、web.xml的启动参数、可变的url映射计划。

而必须在struts.xml中完成的配置有全局results、异常处理、知定义interceptor stacks.

该配置文件的基本形式:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC

"-//Apache Software Foundation//DTDStruts Configuration

2.0//EN"

"http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

<package

name="struts2"

extends="struts-default"

namespace="/struts2">

</package>

</struts>

 

 

 

 

 

<include>标签

用来包含其它与Struts.xml结构相同的配置文件。它只有一个file属性。注意应该先包含再引用。

以上是显示包含文件的方式,而有一些文件是隐式包含的,例如struts-default.xml(包含struts2的核心设置)和struts-plugin.xml(每一个插件的jar中都包含一个,在启动时自动加载)

 

 

 

 

Package标签

用于组织配置项以达到共享公共的属性的目的。

标签的属性:

name –一个唯一的包名

extends –继承的包名,其中父包所有的配置项(包含action的配置)都在子包中有效

namespace –提供url到package的映射。例如两个不同的包,用 namespace 属性定义为 “package1”和“package2”,请求时应用以下格式“/myWebApp/package1/my.action” 和/myWebApp/package2/my.action”

abstract –如果取值为true,通常用作配置组,而且Action的配置不能通过包名来访问

要选择正确的包去继承,这样可以重复使用其中的配置,通常情况下是struts-default.xml中的struts-default包。而如果你要使用插件那么它就会有所不同,你需要查看在插件jar中的说明

 

 

 

Action

这是一个可工作的基本单元,它通常与来自一个用户的请求相关。

Action可以用以下的方式进行使用:

单个结果

class MyAction {

public String execute() throws Exception {

return "success";

}

}

该类是一个POJO类,该类有一个execute方法,你可以配置文件中说明这样就可以用其它的方法名。不论这个方法名叫什么,它都必须返回一个String,这个String表示一个呈现结果的页面路由。

一个最简单的配置如下:

<action name="my"class="com.fdar.infoq.MyAction" >

<result>view.jsp</result>

</action>

根据name属性,确定请求这个Action的URL为/my.action,而扩展名.action是在struts.properties配置文件中设定的。根据class属性确定要执行的Action的完整类名。

 

多种结果

一个复杂的用法是返回多个结果。

class MyAction {

public void String execute() throwsException {

if( myLogicWorked() ) {

return "success";

} else {

return "error";

}

}

}

<action name="my"class="com.fdar.infoq.MyAction" >

<result>view.jsp</result>

<result name="error">error.jsp</result>

</action>

 

 

其中在result的节点中有一个name属性,它总是存在的,如果用户没有指定,则默认取值为success.

插件可以自动完成

“/adduser.action”and the action returned “success”, then

“/adduser-success.jsp”would be rendered.

在Action中可以使用@Results 和 @Result annotations。

Action可以直接返回一个Result实例,而不返回一个String。

Result的类型

"success"结果会返回到一个页面。

"error"结果会返回一个http头到浏览器。

result的类型在result节点中用type属性进行配置,这个属性有一个默认值为dispatcher,它表示用jsp进行显示结果。

 

 

请求与表单数据

struts2用Action来封装请求数据,要求提供相应的setter和getter方法。home.action?framework=struts&version=2

则相应的Action要提供相应的setFramework(StringframeworkName)和setVersion(intversion)

注意setter并不总是需要String类型的参数,struts2中可以在Action中做相应的类型转换。 

它能够自动完成基本类型和基本java对象的转换。也可以自定义转换器。

如果有一个请求为

person.address.home.postcode=2

它能够自动在对象图中做导航例:“person.address.home.postcode”表示getPerson().getAddress().getHome().setPostcode(2)

 

 

 

 

 

 

 

访问业务逻辑

struts2使用了依赖注入,依赖注入能够通过构造函数注入,接口注入和设值注入。struts2使用设值注入。

这意味着可以在Action中提供一个setter方法来进行设值注入业务对象。最优的方案是通过spring框架来注入(可以通过一个插件的形式来配置)。另一个选择是用Plexus或者你自已实现。

而有一些对象是不能被spring框架管理的,例如HttpServletRequest,那么可以用aware接口来完成注入。

注意,webwork本来有自己的注入框架,但是在2.2的版本中被spring框架所有代替。 

拦截器也可以用来管理依赖注入。

 

 

 

 

 

拦截器

struts2中有许多功能是用拦截器完成的,例如:异常处理、文件上传、生命周期回调、验证器。

拦截器从概念上讲如同Servlet中的过滤器或者jdk中的代理proxy类。他们提供了一种预先处理和延后处理Action的能力。就象Servlet中的filter,拦截器能够排序.

用拦截器进行依赖注入:

已经实现的拦截器有:

Spring Framework – the

ActionAutowiringInterceptor interceptor.

Request String and Form Values – the

ParametersInterceptor interceptor.

Servlet-based objects – theServletConfigInterceptortfn tf

interceptor.

前两个拦截器是独立工作的,而最后一个拦截器需要和以下相关的接口一起工作。

SessionAware –通过Map去访问所有Session中的共享数据

ServletRequestAware – 提供访问HttpServletRequest对象的途径。

RequestAware –通过Map去访问所有request中的共享数据

ApplicationAware – 通过Map去访问所有application中的共享数据

ServletResponseAware – 提供访问HttpServletResponse对象的途径。

ParameterAware – 通过Map去访问所有request中的字符串或表单中的值.

PrincipalAware – 提供访问

PrincipleProxy object的途径; 该对象提供了HttpServletRequest的角色验证的方法, 而不是去提供一个代理,允许在Action中独立实现

ServletContextAware – 提供访问ServletContext对象的途径。

 为了能够保证数据注入Action中是正确的,它必须实现必须的接口。

 

 

配置

如果我们想要实现依赖注入,我们必须对Action进行配置.

象其它的配置一样,许多拦截器可以被预先配置,保证你的包继承了struts-default包。

配置拦截器我们必须在<package>下配置<interceptors>例如:

<interceptors>

<interceptor name="autowiring"

class="interceptor.ActionAutowiringInterceptor"/>

</interceptors>

为了保证拦截器应用到每一个Action我们可以使用以下两种方法:

1、为每一个Action配置一个拦截器

<action name="my"class="com.fdar.infoq.MyAction" >

<result>view.jsp</result>

<interceptor-refname="autowiring"/>

</action>

这种方式,可以注入任意个你想要的拦截器,它们会按照配置的顺序被执行.

2.为当前的包指定一个默认的拦截器。

在<package>中包含

<default-interceptor-refname="autowiring"/>

在Struts2中一个Action有7、8个拦截器是比较常见的,如果对于每一个Action都要分别配置是很难进行管理的,所以我们可以用拦截器栈来管理。

下面的例子来自于struts-defalt.xml文件中。

<interceptor-stackname="basicStack">

<interceptor-refname="exception"/>

<interceptor-refname="servlet-config"/>

<interceptor-refname="prepare"/>

<interceptor-refname="checkbox"/>

<interceptor-refname="params"/>

<interceptor-refname="conversionError"/>

</interceptor-stack>

以上配置放在<package>节点之下,其中每个<interceptor-ref>用于引用一个拦截器或一个拦截器栈。

在Action中应用拦截器栈的方法与拦截器一样。

<action name="my"class="com.fdar.infoq.MyAction" >

<result>view.jsp</result>

<interceptor-refname="basicStack"/>

</action>

<default-interceptor-refname="basicStack"/>

 

 

自定义拦截器

需要实现来自xwork框架的接口Inerceptor,它有三个方法需要实现。

public interface Interceptor extendsSerializable {

void destroy();

void init();

String intercept(ActionInvocationinvocation)

throws Exception;

}

实际上,如果没有国际化或清理的需求,有一个AbstractInterceptor可以被继承,这个类没有提供destroy和init方法的实现。

参数ActionInvocation提供运行时的访问。

它允许访问Action自己,上下文(请求参数,Session参数,用户的区域信息等),Action的执行结果,调用Action的方法以及决定是否Action已被调用。

 

 

 

 

 

 

值栈/OGNL

值栈表示一组存放在栈中的对象。

Struts2中将应用范围里的数据以及Action处理的数据都存储在一个区域里。在Struts2中叫做“valueStack”,中文名为“值栈”。而OGNL就是从“值栈”取出数据,并在某些条件下进行数据过滤和计算的表达式语言。在Struts2中值栈作为OGNL的根对象,从值栈中取出自己需要的数据,而且值栈存取数据是按照先入后出的概念。因此查询数据时候往往是值栈中最顶部的数据先被查询出来。更加需要指出的是在值栈中也可以使用索引,可以在指定的索引位置开始搜索数据。

在OGNL中如果搜索的数据不是值栈里存储的数据,而是其他对象中,特别是Struts2ActionContext中的对象,则在访问这些对象时候,前面要加“#”。比如ognl.jsp中访问session和request对象时候代码中在request和session之前就有“#”。

对于数据集合类型,如果根据条件查询该集合里的数据,形成子集合的时候,常用的OGNL还有“?”、“^”、“$”。此三个符号中“?”是取得所有符合条件的数据时使用。“^”是取这些符合条件的数据中索引中第一个或第一条数据。而“$”则正好相反,是取得最后一个或最后一条数据。

 

OGNL表示ObjectGraph Navigational Language,提供了访问值栈的一种统一的方法。

值栈中存放了以下对象:

1.临时对象-在执行期间创建的临时对象,例如在JSP标签中遍历一个集合所产生的值。

2.模型对象-如果模型对象被使用,当有使用的模型对象放在Action之前。

3.Action对象-正在执行的Action

4.被命名的对象-包括#application,

#session, #request, #attr and #parameters和被相应共享范围所引用的对象

访问值栈可以使用不同的方式,通常是通过jsp的标签,或者velocity、freemarker.

比如您向值栈询问一个name属性的值,则会在值栈中访问每一个对象是否有name属性如果有的话就返回,否则继承访问下一个对象直到栈底。

OGNL是一个鲜明特点的表达式语言,用dot符号来导航对象。

它中以进行类型转换,方法调用,集合遍历和生成,完整的内容可以看以下网址:

http://www.ognl.org/2.6.9/Documentation/html/LanguageGuide/index.html

 

 

 

 

 

 

 

 

Result类型

如果我们没有指定type属性则默认为dispatcher,这被用来指定一个jsp页面去显示结果。

<action name="my"class="com.fdar.infoq.MyAction" >

<resulttype="dispatcher">view.jsp</result>

</action>

结果的类型被配置在<package>标签中,与拦截器的配置很相似,name属性用来指定一个唯一的Result类型的标识符,class属性用来指定一个实现类,default属性用来指定一个默认的可以修改的属性。

 

实现Result类型

和拦截器一样,能够自定义Result类型被在你的web应用中进行配置,许多通用的result类型已经创建尽量使用已存在的。

创建一个新的Result类型,实现Result接口

public interface Result extendsSerializable {

public void execute(ActionInvocationinvocation)

throws Exception;

}

 

Results/View技术

重用Action的配置

当不同的请求希望执行相同的Action时,可以在默认的包中定义以下的Action。

<action name="home"class="com.fdar.infoq.HomeAction" >

<result>portal.jsp</result>

</action>

这要在jsp显示时取决于用户的调用时的名字空间,如:

www.myzoo.com/home.action时/portal.jsp会被显示。

www.myzoo.com/asia/home.action时/asia/portal.jsp会被显示。

 

 

 

 

 

 

在配置中使用类型配置符

在应用程序中URL的格式通常为/{module模块}/{entity实体}/{action}.action

例如:“/admin/User/edit.action”, “/admin/User/list.action”

可以配置文件中出现以下的内容

其中{n}对应是星号的内容,从左到右为1-3

<action name=”*/*/*” method=”{3}”

class=”com.infoq.actions.{1}.{2}Action”>

<resultname=”view”>/{1}/update{2}.jsp</result>

<resultname=”list”>/{1}/list.jsp</result>

</action>

 

<!--http://localhost:8080/struts2/example/Login_execute.action

表示调用exaple.Login中的execute方法

-->

       <action name="Login_*" method="{1}"class="example.Login">

           <result name="input">/example/Login.jsp</result>

           <result type="redirect-action">Menu</result>

       </action>

 

但这要使用时要保证在struts.properties或struts.xml中设置

struts.enable.SalashesInActionNames=true

使用可以转变url映射规则

通配符的另一个用途是自定义从url到Action以及调用其方法的映射。

1.必须实现ActionMapper接口,并覆写其中的两个方法

getMapping()

转换url到已知的配置。

getUriFromActionMapping()

转换Action的配置到url.

2.在struts.xml中配置

<constantname="struts.mapper.class"

value="MyActionMapper的完整类名" />

3.struts2自定义了一些ActionMapper

1)Restful2ActionMapper

可以使用以下的格式进行请求http://HOST/PACKAGE/ACTION/PARAM_NAME1/PARAM_VALUE1/PARAM

_NAME2/PARAM_VALUE2

其中PARAM_NAME/PARAM_VALUE没有个数的限制

如果PARAM_NAME为id,可以省略为

http://HOST/PACKAGE/ACTION/PARAM_VALUE1/PARAM_NAME2/PARAM

_VALUE2

 

 

 

struts2

 默认的是dispatcher服务器跳转      

 redirect 重定向分重定向到url和重定向到一个action。

实现重定向,需在struts.xml中定义返回结果类型。

type="redirect"是重定向到一个URLtype="redirect-action" 是重定向到一个action

参数也是在这里指定,action中所做的就是给参数赋值,并return 这个结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值