struts2 的基本常用配置详解

 

一、分析Struts 2相关的配置文件
1、struts2-core-2.*.*.jar/org/apache/struts2/default.properties文件中的部分属性含义:
struts.locale:指定默认的locale。
struts.i18n.encoding:指定默认的编码方案,默认值为UTF-8。在解决中文乱码问题时,可将其设为GBK。
struts.multipart.parser:指定上传文件的解析方式,默认值为jakarta。
struts.multipart.saveDir:指定上传文件的临时存储目录。
struts.multipart.maxSize:指定允许上传的文件的最大字节数,默认为2M。
struts.custom.properties:指定要加载的用户定制的属性文件列表(多个文件以逗号分隔),这些属性文件中的属性设置不会覆盖struts.properties文件中的属性设置。
struts.action.extension:指定由Struts 2处理的请求的后缀,默认为action。
struts.ui.theme:设置Struts 2默认的主题。
struts.i18n.reload:指定是否重新加载资源文件,默认为false。
struts.configuration.xml.reload:指定当struts.xml文件内容改变时,是否重新加载该文件,默认为false。
struts.custom.i18n.resources:指定要加载的国际化资源包的基名,多个以逗号分隔。
struts.configuration.files:指定Struts 2默认自动加载的配置文件列表,多个以逗号分隔。***********

修改上述属性值有三种方式:
第一种:在Web应用程序的WEB-INF/classes目录下新建属性文件struts.properties,以键值对的方式配置。
第二种:在Web应用程序的WEB-INF/classes目录下的struts.xml中配置,增加<constant name=" " value=" "/>节点。
第三种:在web.xml的Struts 2过滤器中配置,增加<init-param></init-param>节点。


2、struts2-core-2.*.*.jar/struts-default.xml
Struts 2 框架的基础配置文件,为框架提供默认配置,由框架自动加载。


3、struts.xml
Struts 2 框架的核心配置文件,主要用于配置和管理开发人员编写的action。此文件通常位于Web应用程序的WEB-INF/classes目录下。

常量(constant)配置:
<constant name="struts.custom.i18n.resources" value="messages"/>

包(package)配置:Struts 2 中的包类似于Java中的包。
name属性必选,包的名字必须是唯一的。
extends属性可选,允许一个包继承(扩展)一个或多个先前定义的包中的配置,如果指定多个包,则以逗号分隔。
abstract属性可选,如果其值为true,则该包被定义为抽象的,抽象包不能有action的定义,它可被其他的包所继承(扩展)。
namespace属性可选,用于指定命名空间,当Struts 2 接收到一个请求的时候,它会将请求URL分为namespace和action名称这两个部分,然后Struts 2 就会从struts.xml中查找namespace/action这个命名对,如果没有找到,Struts 2 就会在默认的命名空间中搜索相应的action名称。默认命名空间用空字符串("")表示。当没有指定namespace属性时,使用的是默认命名空间。当指定namespace属性时,使用的是指定的命名空间。例如:namespace="/user"。页面上使用<s:form action="login" method="post" namespace="/user" />

包含(include)配置:便于团队协作,通常会将项目划分为多个较小的模块,每个模块单独开发和管理。被包含的文件通常放在Web应用程序的WEB-INF/classes目录下,也可以放在某个包里面。
例如:<include file="struts-my.xml">
或者
<include file="com/mystruts2/user/struts-my.xml">

 

二、模型驱动
1、属性驱动
Struts 2 的属性驱动是指JSP页面中的form表单元素在action中都有一个属性与之对应。

2、模型驱动
Struts 2 中为每一个Action提供一个POJO对象,用来封装表单元素。
使用模型驱动的action需要实现ModelDriven接口。
public class LoginAction extends ActionSupport implements ModelDriven<UserModel>{ 
 private UserModel userModel = new UserModel();

 @Override
 public String execute() throws Exception {
  System.out.println("username: " + userModel.getUsername() );
  System.out.println("password: " + userModel.getPassword() );
  return super.execute();
 }

 public UserModel getModel() {
  return userModel;
 }
}

3、模型驱动和属性驱动的Action的区别:
(1).模型驱动的Action必须实现com.opensymphony.xwork2.ModelDriven接口,而且要提供相应的泛型,这里就是具体使用的POJO类。
(2).实现ModelDriven的getModel方法,其实就是简单的返回泛型的一个对象。
(3).在Action中提供一个泛型的私有对象,即定义一个UserModel类型的userModel对象。
完成上述配置后,Action就会去自动调用UserModel的setter方法将表单中的name属性的值赋给UserModel中的相应属性。
那么到底是用属性驱动,还是用模型驱动呢?
这个问题困扰了很多Struts 2 的初学者,这里提供一些建议:
(1).统一整个系统中Action使用的驱动模型,即要么都使用属性驱动,要么都使用模型驱动。
(2).如果DB中的持久层对象与表单中的属性都是一一对应,那么就使用模型驱动。
(3).如果表单的属性不是一一对应,那么就应该使用属性驱动,否则,你的系统就必须提供两个Bean,一个对应表单提交的数据,另一个用于持久层。

 

三、防止重复提交
原理:
当页面第一次生成的时候<s:token></s:token>会生成一个隐藏表单域,该表单域包涵一个值,此值也同样被存放到服务器端的session中;当页面第一次提交的时候token拦截器会比较这两个值是否相同,如果相同则认为是第一次提交,在第一次提交后会把session中的这个值清空,表单若再一次提交时则session当中没有值即两个值不相同提交失败。

1、在需要防止重复提交的页面上添加<s:token/>标签。

2、由于token拦截器没有配置在默认拦截器栈中,所以需要在action中手动配置token拦截器。

3、重复提交时返回的result name为:invalid.token。需要在action中配置result。
相关配置如下:
<action ....>
    ...
    <result name="invalid.token">/register.jsp</result>
    ...
</action>

<interceptor-ref name="token" />
<interceptor-ref name="defaultStack" />

3、用<s:actionerror />提取重复提交时的错误提示信息。
struts.messages.invalid.token=The form has already been processed or no token was supplied, please try again.

 

四、自动显示等待页面
有时候对某个请求的处理可能会耗费较长的时间,在这种情况下,向用户显示一个等待页面更为友好一些。
在Struts 2中通过ExecuteAndWaitInterceptor拦截器在用户提交表单后向用户输出一个等待页面,等待页面定时向服务器提交请求,以确定服务器的操作是否完成。如果请求已经处理完毕,ExecuteAndWaitInterceptor拦截器将把请求导向到结果页面。当一个action的执行时间超过5或10分钟时,ExecuteAndWaitInterceptor拦截器可以防止HTTP请求超时。
ExecuteAndWaitInterceptor拦截器没有包含在defaultStack拦截器栈中,所以你需要为你的Action手动配置引用这个拦截器。需要注意的是,这个拦截器必须被配置为引用的拦截器中的最后一个,这是因为它会停止后续的所有操作,在它之后的拦截器不会被调用。
给你的Action配置wait结果映射,指向一个等待页面。ExecuteAndWaitInterceptor拦截器默认自带了一个等待页面,路径为org/apache/struts2/interceptor/wait.ftl,这个等待页面比较简单。
因为被ExecuteAndWaitInterceptor拦截器拦截的Action将会在单独的线程中执行,所以在这个Action中你不能使用ActionContext,因为ActionContext是线程本地的。

<meta http-equiv="refresh" content='3;url=<s:url includeParams="all"/>'>

You can click this link to <a href="<s:url includeParams="all"/>">refresh</a><br>
正在加载,请稍后。。。。。!

 

五、操作Servlet API
1、IOC方式
ServletContextAware接口
ServletRequestAware接口
ServletResponseAware接口
SessionAware接口

action类实现ServletRequestAware接口。
public class LoginAction extends ActionSupport implements ServletRequestAware{
   ...
   private HttpServletRequest request;

   public void setServletRequest(HttpServletRequest request) {
      this.request = request;
   }
   ...
}
action类实现SessionAware接口。
public class LoginAction extends ActionSupport implements ServletRequestAware,SessionAware{
   ...
   private HttpServletRequest request;

   private Map<String, Object> session;

   public void setServletRequest(HttpServletRequest request) {
      this.request = request;
   }
   public void setSession(Map<String, Object> session) {
   this.session = session; 
   }
   ...
}

2、非IOC方式
这种方式主要是利用了com.opensymphony.xwork2.ActionContext类以及org.apache.struts2.ServletActionContext类,示例如下所示。
获得request对象:
A.HttpServletRequest request = ServletActionContext.getRequest();
B.ActionContext ct = ActionContext.getContext();
   HttpServletRequest request = (HttpServletRequest)ct.get(ServletActionContext.HTTP_REQUEST);
获得session对象:
在Struts 2中底层的session都被封装成了Map类型,我们称之为SessionMap,而平常我们所说的session则是指HttpSession对象。
ActionContext ct = ActionContext.getContext();
Map session = (Map)ct.get(ActionContext.SESSION);
得到这个SessionMap之后我们就可以对session进行读写了。如果我们想获取原始的HttpSession,可以首先获取HttpServletRequest对象,然后通过request.getSession()来取得原始的HttpSession对象。不过,一般情况下SessionMap已经可以完成所有的工作,因此不必再去碰底层的session了。

 

六、动态方法调用(DynamicMethodInvocation)
1. 在配置action时指定:<action name="****" class="****" method="methodName">
2. 在客户端(即页面)指定:<s:form action="actionName!methodName">
3. 使用通配符指定:<action name="*Login" class="com.struts.action.LoginAction" method="{1}">,若form中action的url为helloLogin,则调用LoginAction的hello方法来处理业务。此种方式简化了配置,但是使得程序不明了,不提倡使用该方法。

 

七、结果类型(result type)
chain
    用来处理Action链,将一个action的执行与另外一个配置好的action串连起来。用第一个action的getter方法和第二个action的setter方法来完成action之间属性的复制。
    com.opensymphony.xwork2.ActionChainResult  
 
dispatcher
    用来转向JSP页面,这是默认的结果类型。如果在action配置中没有指定其他的结果类型,它就会被使用。
    org.apache.struts2.dispatcher.ServletDispatcherResult  
 
freemaker
    处理FreeMarker模板。  
    org.apache.struts2.views.freemarker.FreemarkerResult  
 
httpheader
    控制特殊HTTP行为的结果类型。   
    org.apache.struts2.dispatcher.HttpHeaderResult  
 
redirect
    重定向到一个URL。    
    org.apache.struts2.dispatcher.ServletRedirectResult  
 
redirectAction
    重定向到一个Action。
    org.apache.struts2.dispatcher.ServletActionRedirectResult  
 
stream
    向浏览器发送InputStream对象,通常用来处理文件下载,还可用于返回AJAX数据。 
    org.apache.struts2.dispatcher.StreamResult  
 
velocity 
    处理Velocity模板。
    org.apache.struts2.dispatcher.VelocityResult  
 
xslt  
    处理XML/XLST模板。
    org.apache.struts2.views.xslt.XSLTResult  
 
plainText  
    显示原始文件内容,例如文件源代码。
    org.apache.struts2.dispatcher.PlainTextResult
   
redirect与redirectAction区别:
1、type="redirect"不但可以将请求转至action,还可以转至其它的Web资源(比如jsp页面)。type="redirectAction"只能将请求转至action。
redirectAction或者redirect传递参数:
<result name="success" type="redirectAction或者redirect">  
     showpreinfo?preinfo.order_number=${preinfo.order_number}&amp;preinfo.company_name=${preinfo.company_name}
</result>

 

八、异常处理
Struts 2进行异常处理首先需要添加exception拦截器,由于defaultStack拦截器栈已经引入了exception拦截器,所以不需要手动引用。
Struts 2中异常映射声明有两种:全局声明和局部声明。在struts.xml文件中添加<global-exception-mappings>标签用于配置全局异常映射声明。异常映射(<exception-mapping>)有两个属性:exception属性指定了异常的类型,result属性指定了发生异常时执行的result。
当异常发生时,它会先寻找局部异常映射,未找到则会寻找全局异常映射。若匹配上就会根据result属性按照先局部后全局的方式寻找相同名字的result,然后就像action调用result一样执行对应的result。注意:当异常发生时,Struts 2会根据抛出的异常去映射文件中寻找在继承关系上与该异常最接近的映射进行匹配。
例如,action抛出一个IOException,这个异常是Exception的直接子类,所以会匹配到Exception映射。再者,action抛出一个BatchUpdateException,它既是SQLException的子类,同时也是Exception的子类,但是它和SQLException的继承关系最接近,所以它会匹配到SQLException。

<struts>
    <package name="struts2" extends="struts-default">
        ...
        <global-results>
      <result name="sql">/exception.jsp</result>
      <result name="root">/exception.jsp</result>
     </global-results>
     <!-- 全局异常声明 -->
     <global-exception-mappings>
      <exception-mapping result="sql" exception="java.sql.SQLException"/>
      <exception-mapping result="root" exception="java.sql.Exception"/>
     </global-exception-mappings>
     
     <!-- 模型驱动 -->
     <action name="register2" class="com.struts2.action.RegisterAction2">
      <!-- 局部异常声明 -->
      <exception-mapping result="my" exception="com.struts2.exception.MyException"/>
      <result name="my">/exception.jsp</result>
      <result name="success">/result.jsp</result>
      <result name="input">/register.jsp</result>
     </action>
        ...
    </package>
</struts>
缺省情况下异常映射拦截器(ExceptionMappingInterceptor)添加下列值到Value Stack中:
①. exception  异常对象本身
②. exceptionStack  stack trace的值

例如指定发生异常时,转到一个JSP页面,可以在JSP页面中输出异常信息,如下所示:
<h3>出错信息</h3>
<p>
  <s:property value="%{exception.message}"/>
</p>
<h3>详细信息</h3>
<p>
  <s:property value="%{exceptionStack}"/>
</p>

 

九、MVC与Struts 2:
M:
C:StrutsPrepareAndExecuteFilter(核心控制器,该控制器负责拦截和过滤所有的用户请求)、action(业务控制器)。
V:JSP可作为视图,还允许使用其他的视图技术,如FreeMarker、Velocity等作为视图。当Struts 2的控制层调用业务逻辑组件处理完用户请求后,会返回一个字符串,该字符串代表逻辑视图,它并未与任何的物理视图技术关联。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值