Struts2(一)Struts2配置详解

来源:互联网 发布:手机语言翻译软件 编辑:程序博客网 时间:2024/06/05 08:12

一、Struts2概述

I.在很长一段时间Struts1在MVC框架中占有绝对的地位,虽然Struts1可以很好地实现将控制与业务逻辑相分离,但是其自身仍然存在这一定的缺陷
1.表现层支持单一
   Struts1只支持jsp作为表现层,而在实际开发中不一定只是使用jsp作为表现层,如FreeMarker、Velocity等。
2.对ServletAPI依赖
   jsp+Servlet+JavaBean方式属于Model II的开发模式,而Struts1也是基于ModelII的开发模式,因此会在其中应用大量的ServletAPI,而ServletAPI需要Web容器进行初始化,从而进一步对web容器产生依赖
3.不利于代码复用
   在Struts开发的代码中除了自己定义的类外,还必须使用Struts1中的某些类(如actionForm),这样一来,与Struts1的类耦合在一起很难进行代码重用 Struts2在设计之初,更多的是以WebWork的设计思想为核心,从应用角度也更接近于WebWork的使用习惯。Struts1与WebWork的优势互补是的Struts2拥有更加广阔的前景
II.开发Struts2应用一般由两大部分组成
1.确认环境
(1)将Struts2框架支持jar包引入项目中
(2)修改工程的web.xml文件,配置过滤器。
2.代码编写
(1)编写开发处理请求的Action类,实现具体的请求方法(方法返回字符串类型)
(2)编写struts.xml文件,对Action进行配置
(3)编写与Action相关的JSP页面

二、Struts2的应用

1.创建好web项目Struts2Demo,在项目中引用Struts2的jar包,下面来做一个登录的Demo
Struts2项目所需jar包文件名说明struts2-core-xxx.jarStruts2框架的核心类库xwork-core-xxx.jarXWork类库,Struts2的构建基础ognl-xxx.jarStruts2使用的一种表达式语言类型freemarker-xxx.jarStruts2的标签模板使用类库javassist-xxx.GA.jar对字节码进行处理commons-fileupload.jar文件上传时需要使用commons-io-xxx.jarJava IO扩展Commons-lang-xxx.jar包含了一些数据类型的工具类点击下载Struts2 API

2.配置web.xml文件

[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app version="3.0"   
  3.     xmlns="http://java.sun.com/xml/ns/javaee"   
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  5.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
  6.     http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">  
  7.   <display-name></display-name>   
  8.   <welcome-file-list>  
  9.     <welcome-file>index.jsp</welcome-file>  
  10.   </welcome-file-list>  
  11.   <!--   
  12.     1.使用filter元素定义过滤器,  
  13.       filter-name指定过滤器名字(自定义),  
  14.       filter-class指定对应的java类的完整类名,这里固定指定为org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter类  
  15.     2.使用filter-mapping元素表示将所有的请求拦截并交给上面的filter-class进行处理。  
  16.    -->  
  17.   <filter>  
  18.     <filter-name>struts2</filter-name>  
  19.     <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>  
  20.   </filter>  
  21.   <filter-mapping>  
  22.     <filter-name>struts2</filter-name>  
  23.     <url-pattern>/*</url-pattern>  
  24.   </filter-mapping>  
  25. </web-app>  
3.创建com.wzj.action.HelloWorldAction类,并实现com.opensymphony.xwork2.Action接口
(在以后的应用中更多的是继承com.opensymphony.xwork2.ActionSupport类,后续讲解),其中只有一个execute方法
[java] view plain copy
  1. package com.wzj.action;  
  2. import com.opensymphony.xwork2.Action;  
  3.   
  4. public class HelloWorldAction implements Action{  
  5.   
  6.     /** 
  7.      * 定义字段name、password,并提供其get、set方法 
  8.      * 当请求过来的时候Struts2框架会自动将表单中的数据映射到字段中 
  9.      * 注意字段名称和表单中的控件名称对应,且字段需提供get、set方法 
  10.      */  
  11.     private String name;  
  12.     private Strig password;  
  13.       
  14.     /** 
  15.      * 当Struts2处理请求时,在默认配置下调用的方法 
  16.      */  
  17.     @Override  
  18.     public String execute() throws Exception {  
  19.         if (this.name.equals("张三")&&this.password.equals("123")) {  
  20.             return "success";  
  21.         }else {  
  22.             return "input";  
  23.         }  
  24.     }  
  25.   
  26.     //省略get、set方法..  
  27. }  
4.在src下创建名为struts.xml文件,并做如下配置
[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE struts PUBLIC  
  3.     "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"  
  4.     "http://struts.apache.org/dtds/struts-2.1.7.dtd">  
  5. <struts>  
  6.     <!--   
  7.         1.package:用于定义Struts2处理请求的逻辑单元,  
  8.           name属性:必须且唯一,用来指定包的名称(被其他包引用)  
  9.           extends属性:类型java的extends关键字,指定继承自哪个包  
  10.         2.action:用于配置Struts2的工作单元Action类,将请求中的URI(action名字)对应到一个Action类,让其进行处理请求  
  11.           name属性:必须的,用来表示action的名称,class属性可选,用来指定哪个类来进行处理,  
  12.                       不指定的话则默认是com.opensymphony.xwork2.ActionSupport类  
  13.         3.result:设定Action类处理之后系统将怎么做,或者跳转到哪个页面  
  14.           name属性:指定字符串名称,必须和Action中的execute方法返回的字符串想进行匹配  
  15.           result元素的值表示与逻辑视图名称对应的物力资源之间的映射,用来指定这个结果对应的实际资源的位置  
  16.      -->  
  17.     <package name="UserPackage" namespace="/" extends="struts-default">  
  18.         <action name="helloWorld" class="com.wzj.action.HelloWorldAction">  
  19.             <result name="success">/success.jsp</result>  
  20.             <result name="input">/index.jsp</result>  
  21.         </action>  
  22.     </package>  
  23. </struts>  
5.编写index.jsp页面
[html] view plain copy
  1. <body>  
  2.     <form action="helloWorld" method="post">  
  3.         <p>用户名:<input type="text" name="name"/></p>  
  4.         <p>密  码:<input type="text" name="password"/></p>  
  5.         <input type="submit" value="提交"/>  
  6.      </form>  
  7. </body>  
6.启动项目,并访问首页http://localhost:8080//Struts2Demo/index.jsp

点击提交后页面跳转到success.jsp。
7.简单流程总结
(1)浏览器通过页面form表单发送请求名为helloWorld的action至服务器
(2)服务器接收到请求以后,根据web.xml的配置,将所有的请求都发送给Struts2内置的StrutsPrepareAndExecuteFilter过滤器
(3)然后过滤器会默认去查找名字为struts.xml的配置内容,根据配置,将请求发送给HelloWorldAction类进行处理,并调用默认的execute方法
(4)根据execute方法的返回值去匹配result元素的name属性值,若匹配,则跳转到对应的视图
(5)页面显示数据
通过上面实现的一个简单的Demo,相信大家一定会有很多的疑问,没关系,我们一一道来。

三、Struts2配置详解

1.web.xml
        任何一个Web应用程序都是基于请求/响应模式构建的,所以无论哪种MVC框架都离不开web.xml文件的配置;Struts2需要在web.xml中配置其核心控制器——StrutsPrepareAndExecuteFilter,用于初始化并处理请求。StrutsPrepareAndExecuteFilter可以包含一些要初始化的参数,如config——要加载的XML文档,如果没有设置此参数,Struts2将默认加载struts-default.xml、struts-plugin.xml、struts.xml文件。
2.struts.xml
①使用constant元素配置常量,改变Struts2的一些行为,如下可以处理中文乱码问题:

[html] view plain copy
  1. <struts>  
  2.     <!--省略-->  
  3.     <constant name="struts.i18n.encoding" value="UTF-8"></constant>  
  4.     <package name="UserPackage" namespace="/" extends="struts-default">  
  5.     <!--省略-->  
  6.     </package>  
  7. </struts>  
②package中的属性和其他子元素已在注释中详细解释,这里看一下namespace属性:
        namespace是可选属性,该属性定义该包中action的命名空间,如果没设置,则此action将被放入默认命名空间。Struts2框架用action的名称和它所在的命名空间来标示一个action。默认命名空间用""表示,也可以使用"/"定义一个根命名空间,两者是有区别的。当Struts2接收到一个请求时,框架会将url分为namespace和action两部分,框架首先会在namespace中查找action,如果找不到则进入默认命名空间查找。
3.action
(1)action的作用

在MVC框架中,控制器是由两部分组成,分别如下:
①核心控制器(Filter):用于拦截用户请求并进行处理
②业务控制器(Action):调用相应的Model类实现业务需求,返回结果
        编写Action可以通过新建Java类,然后实现com.opensymphony.xwork2.Action接口的方式,也可以通过继承com.opensymphony.xwork2.ActionSupport类的方式。ActionSupport是Action接口的一个实现类。
action对于开发者而言才是核心,action有如下作用:
①封装工作单元
        可以把action看做控制器的一部分,其主要就是控制业务逻辑
②数据转移的场所
        在action中可以定义需要用到的字段甚至对象,如示例中演示所示,但注意要为成员字段提供get、set方法同样也可以将多个字段封装成对象,但是表单中的名称需要改变,如下:
将name和password封装成User对象,Action 中:
[java] view plain copy
  1. package com.wzj.action;  
  2.   
  3. import com.opensymphony.xwork2.Action;  
  4.   
  5. public class HelloWorldAction implements Action{  
  6.   
  7.     /** 
  8.      * 直接定义User,省略get、set方法 
  9.      */  
  10.     private User user;  
  11.     /** 
  12.      * 当Struts2处理请求时,在默认配置下调用的方法 
  13.      */  
  14.     @Override  
  15.     public String execute() throws Exception {  
  16.         if (user.getName().equals("张三")&&user.getPassword().equals("123")) {  
  17.             return "success";  
  18.         }else {  
  19.             return "input";  
  20.         }  
  21.     }     
  22. }  

表单中:

[html] view plain copy
  1. <form action="helloWorld" method="post">  
  2.     <p>用户名:<input type="text" name="use.name"/></p>  
  3.     <p>密    码:<input type="text" name="user.password"/></p>  
  4.     <input type="submit" value="提交"/>  
  5. </form>  
③返回结果字符串
在com.opensymphony.xwork2.Action接口中定义了五个常量,用来表示返回结果字符串,所以为了防止书写错误可以直接使用其中定义好的常量——ERROR、INPUT、LOGIN、NONE、SUCCESS
(2)action中的方法
        如果没有进行配置,则默认情况下框架会调用execute方法,当然也可以在同一个action中定义多个方法(格式和execute方法一样,返回字符串),这时候就要在
struts.xml文件的action中进行配置:
[html] view plain copy
  1. <!--为action元素添加method 方法,名字对应自定义的方法名称-->  
  2.         <action name="helloWorld" class="com.wzj.action.HelloWorldAction" method="login">  
  3.             ...  
  4.         </action>  
(3)action中动态方法调用
        为了减少Action的数量,可以使用动态方法进行处理。
动态方法调用是指表单元素的Action并不是直接等于某一个Action的名称,而是通过在Action名称中使用感叹号(!)来标示要调用的方法名称,格式为:actionName!methodName
例如:
[html] view plain copy
  1. <action name="user" class="com.wzj.action.HelloWorldAction">  
  2.     <!-- 省略...... -->  
  3. </action>  
当请求user!login时则调用HelloWorldAction类中的login方法;
当请求user!register时则调用HelloWorldAction类中的register方法
        基于这种方式会带来安全隐患考虑,在实际应用中很少用这种方式,建议少使用。如果使用method方式指定方法名的话,那么问题又来了,一个请求对应着一个Action,开发过程中必然struts.xml中的action元素的数量会庞大,所以Struts2框架就为我们提供了通配符方式来解决这种问题。
(4)action中使用通配符
在action元素中的name属性支持通配符操作,例如:
[html] view plain copy
  1. <!--   
  2.     1.使用*来表示实际请求的名称字符串  
  3.     2.使用{1}的方式来获取到实际的*代表的值  
  4.  -->  
  5. <action name="user-*" class="com.wzj.action.HelloWorldAction">  
  6.     <result name="success">/{1}_success.jsp</result>  
  7.     <result name="input">/{1}.jsp</result>  
  8. </action>  
加入请求"user-login",则"*"的值就为login,表达式{1}的值就是name属性中第一个*的值
(5)配置默认的action
如果请求一个不存在的action,则页面肯定会抛出错误,为了解决这个问题,框架允许指定一个默认的action
[html] view plain copy
  1. <package name="UserPackage" namespace="/" extends="struts-default">  
  2.     <!-- 指定默认action使用default-action-ref元素 -->  
  3.     <default-action-ref name="helloWorld"></default-action-ref>  
  4.     <action name="helloWorld" class="com.wzj.action.HelloWorldAction" method="login">  
  5.         <result name="success">/success.jsp</result>  
  6.         <result name="input">/index.jsp</result>  
  7.     </action>  
  8. </package>  
4.result
        当Action处理用户请求结束后,会返回一个字符串——逻辑视图的名称,然后再与result元素的name属性值进行匹配,并跳转到result元素的值——物理视图名称。
[html] view plain copy
  1. <result name="success">/success.jsp</result>  
(1)result中有一个type属性,表示怎样转到结果视图(转发、重定向...)
①dispatch类型——默认的结果类型,表示转发到物理视图
②redirect类型——将请求重定向到物理视图,之前request中的数据将丢失
③redirectAction类型——将请求重定向到action名称
④chain类型——将请求转发到action名称
⑤Struts2定义的类型不止这些,可以在struts2-core-2.1.8.jar/struts-default.xml文件中找到名为"struts-default"的,其中定义了很多类型:

(2)全局结果
       之前配置的result都是定义在action元素内部,不能供其他action使用,多个action可能需要访问同一个result,这时全局结果就派上了用场。全局结果也在包中定义:
[html] view plain copy
  1. <package name="UserPackage" namespace="/" extends="struts-default">  
  2.     <global-results>  
  3.         <result name="error">error.jsp</result>  
  4.     </global-results>  
  5.     <!--省略-->  
  6. </package>  
当action中的请求处理完之后会首先在本Action中进行匹配result,如果匹配不成功则去全局结果中匹配。