Struts 2 常用技术

Struts 2 常用技术

《独门架构——java web 开发应用详解》 ch 9

1. 常用类和接口

1.1 getter 和 setter 方法

Struts 2 的 Action 类可以是一个普通的 POJO 类,类中须有一个execute()方法来处理请求。
Action 类的属性 的gettersetter方法 ,不仅可以封装HTTP请求参数,同时可以为要转入的页面传递处理结果信息。但Struts 2不区分属性封装的是请求参数还是处理结果,因而,Struts 2的标签不仅可以输出处理结果,也可以输出请求参数。
如,设Action类中有属性 result用于返回处理结果,并生成了 gettersetter方法,则在结果jsp中可使用<s:property value="result"/>来输出结果值。

1.2 Action 接口

Struts 2提供了一个Action接口,定义了一些常用结果常量,如Action.SUCCESS="success";,以及一个 execute()方法。

若Struts 2的控制器类实现了Action接口,但使用了其他方法,如process()来处理请求,而不是默认的 execute()方法,此时 execute()方法也是必须要实现的。
不过这样做事画蛇添足了。若只想用其中的常量,使用Action.SUCCESS或静态导入import static com.opensymphony.xwork2.Action.*,然后直接写 SUCCESS 即可。

1.3 ActionSupport 类

ActionSupport 类是很多Struts 2内建接口(包括Action接口)的默认实现。控制器类(Action类)继承ActionSupport可以简化开发。

ActionSupport 类中的execute()方法的实现,只是返回了一个SUCCESS

1.4 通过 ActionContext 访问 Servlet API

Struts 2中Action不能直接访问 Servlet API。
Web 中最常访问 Servlet API 的是 HttpServletRequest、HttpSession 和 ServletContext,分布对于JSP中的request、session和application。
Struts 2 的 ActionContext 类可使用两种方法来访问 ServletAPI:
- getXxx 方法获得Map对象
- get 方法获得相应的 Servlet API 类的对象实例

getXxx方法

1. getContext:返回ActionContext对象。对象的 put 方法可加入 k-v 对,相当于使用  HttpServletRequest 类的setAttribute方法加入 k-v 对。get 方法类似
2. getApplication:Map 对象
3. getSession: Map对象
例:
         ActionContext ctx = ActionContext.getContext();     Map app = ctx.getApplication();     Map session = ctx.getSession();     

get方法

ServletContext ctx = (ServletContext)ActionContext.getContext().get(SERVLET_CONTEXT);
HttpServletRequest request = ( HttpServletRequest ) ActionContext.getContext().get(HTTP_REQUEST);
HttpServletResponse response= ( HttpServletResponse   ) ActionContext.getContext().get(HTTP_RESPONSE);

通过ServletActionContext直接getResponse()getRequest()

1.5 通过感知拦截器访问 ServletAPI

org.apache.struts2.interceptor包中有一类名称含 Aware 的拦截器类。通过它们, 可获得相应的 Servlet API 对象或向相应的 Servlet API 对象写入 K-V 对的Map对象:
1. ApplicationAware接口:获得和ServletContext关联的Map对象
2. CookieAware接口:Cookie数组关联的Map对象
3. ParameterAware接口:和请求参数关联的Map对象
4. ServletRequestAware接口:获得HttpServletRequest对象
5. ServletResponseAware接口:获得HttpServletResponse对象
Action类只要实现上述接口,即可获得相应的Map对象或ServletAPI对象。

一般定义本地对象(如private HttpServletRequest request;),然后通过其 gettersetter方法应用即可

1.6 动态方法处理多个提交请求

Action类的默认请求处理方法是execute()方法(即使没有实现 Action 接口)。但可以在不修改配置文件的条件下改变处理方法。如,通过process()方法处理请求,而execute()方法处理另一请求。
此时访问process需要使用特殊的 Action URL:~/actionname!process.action,即在 action 名称后面加,然后紧跟要调用的方法名

1.7 通过 method 属性处理多个请求

基本原理: 在配置文件中为同一个 Action 类指定多个 name 值,这样一个 Action 类就变成多个 Action 类了,再通过<action>标签的 method 属性为每一个 Action 类指定一个处理请求的方法。
如,让  cn.action.LoginRegisterAction 类同时能够处理 login 和 register 请求:

<package name="struts2" extends="struts-default" namespace="/ch9">
    <action name="loginAction" class="cn.action.LoginRegisterAction" method="login">
        <result name="success">/jsp/success.jsp</result>
    </action>
    <action name="register Action " class="cn.action.LoginRegisterAction" method=" register ">
        <result name=" register ">/jsp/register.jsp</result>
    </action>
    ...
</package>

1.8 在配置中使用通配符

 标签的 name/class/method 都支持通配符。通配符使得配置更加简单而易于维护。
若采用下面的配置(name=*Action),任何以 Action 结尾的action,如 / loginAction  等都可以匹配,且此时 method 属性的值为Action名中的第一个值 login。

<action name=" * Action" class="cn.action.LoginRegisterAction" method="{1}">
    <result name="success">/jsp/success.jsp</result>
</action>

class属性也可以使用通配符,如

<action name=" * Action" class="cn.action.{1}Action" method="{1}">
    <result name="result">/jsp/result.jsp</result>
</action>

由于Java中类的名称一般是 开头大写,方法名称开头小写,因此,若想达到  cn.action.{1}Action中 {1} 值为大写,只能使用两个通配符来表达,如 "*_*",即

<action name=" *_* Action" class="cn.action.{1}Action" method="{2}">
    <result name="result">/jsp/result.jsp</result>
</action>

*_* 中第一个*为类名,第二个*为方法名,如 User_add , 对应的类是  cn.action.UserAction,方法(method)是 add .  等价的配置是

<action name="User _add Action" class="cn.action.UserAction" method="add">
    <result name="result">/jsp/result.jsp</result>
</action>

2 Result - 结果

一般Action只处理用户请求,不直接负责提供对浏览器的响应。Action中请求处理完成之后,返回一个字符串,将结果交由视图资源来完成。
控制器的作用应该是控制将哪个视图呈现给用户

2.1 配置 result

Action中方法处理请求之后返回的字符串称为 结果名 或 视图名。结果可通过 <result>子标签进行配置。一个action可有多个 <result>子标签。
 <result> 有两个属性name 和 type
 - name:  结果名 ,action返回的字符串必须和其的一个<result>标签的name属性相匹配。
 - type: 结果类型。 type 的默认值是 dispatcher(此时可以省略type属性),即转发,相当于使用 forward 方法。
 
 全局结果可使用<global-results>来定义:
   <global-results>      <result name="success">/success.jsp</result>  </global-results>  

2.2 result 类型

Struts2的result中可使用的type可以在 struts-default.xml中找到,包括chainfreemarkerredirect等;

<package name="struts-default" abstract="true" strict-method-invocation="true">
        <result-types>
            <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
            <result-type name="dispatcher" class="org.apache.struts2.result.ServletDispatcherResult" default="true"/>
            <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
            <result-type name="redirect" class="org.apache.struts2.result.ServletRedirectResult"/>
            <result-type name="redirectAction" class="org.apache.struts2.result.ServletActionRedirectResult"/>
            <result-type name="stream" class="org.apache.struts2.result.StreamResult"/>
            <result-type name="velocity" class="org.apache.struts2.result.VelocityResult"/>
            ...
        </result-types>
        ...
</package>        
```    
有些类型需要在相应的**插件包**中找到,如 **`json`**类型位于`json-plugin`下面的`struts-pliugin.xml`中。注意package的名称是`json-default`,**使用json类型时其package的**`extends="json-default"`
                             ... ```

2.2 通配符配置 result

<action name=" * Action" class="cn.action.{1}Action" method="{1}">
    <result name="result">/jsp/{1}.jsp</result>
</action>

为了安全等原因,JSP文件一般放到 WEB-INF 目录中,因为 WEB-INF 中的资源客户端无法直接访问。在strut2中可以通过Action进行转发实现jsp文件的访问。具体方法是配置一个name=“*”,不指定 class (此时默认是ActionSupport类)的action:

<package name="struts2" extends="struts-default" namespace="/ch9">
   <!-- 配置其他action -->
   ...
   <!-- 配置访问jsp的action:处理所有无效的action -->
    <action name="*" >
        <result name="success">/WEB-INF/jsp/{1}.jsp</result>
    </action>
    ...
</package>

此时访问url:  http://localhost:8080/ch9/a.action, 由于默认的action类是ActionSupport,其execute方法返回success,因此访问会转到/WEB-INF/jsp/下面的a.jsp

2.3 用请求参数指定 result

由于Action的属性既可以获得请求参数值,也可以传递参数值(可在要转入的jsp页面中使用EL表达式获得其值),因此可通过请求参数来指定结果的URL。
例如在类中定义参数 forward,设置其 getter/setter方法,请求执行之后,将jsp页面名称赋予 forward 参数,即可通过url来访问web-inf下的资源:

   <!-- 配置其他action -->
   ...
   <!-- 配置访问jsp的action:处理所有无效的action -->
    <action name="forwardAction" class="..." >
        <result name="success">/WEB-INF/jsp/${forward}.jsp</result>
    </action>

3 模型驱动

ModelDriven即用一个JavaBean将用户请求和处理结果单独封装在一起,然后让action同时实现ModelDriven接口。
使用getModel().setResult("resultMsg");之后,可以在JSP中使用<s:property value="model.result"><s:property value="result">获取处理结果值。

原文地址:https://www.cnblogs.com/yes-V-can/p/5946997.html