struts2中s:action,s:param参数的传递与获取方法
struts1和struts2有什么区别
1.都是MVC的WEB框架,
2 struts1的老牌框架,应用很广泛,有很好的群众基础,使用它开发风险很小,成本更低!struts2虽然基于这个框架,但是应用群众并多,相对不成熟,未知的风险和变化很多,开发人员相对不好招,使用它开发项目的风险系数更大,用人成本更高!
3.struts2毕竟是站在前辈的基础设计出来,它会改善和完善struts1中的一些缺陷,struts1中一些悬而未决问题在struts2得到了解决。
4.struts1的前端控制器是一个Servlet,名称为ActionServlet,struts2的前端控制器是一个filter,在struts2.0中叫FilterDispatcher,在struts2.1中叫StrutsPrepareAndExecuteFilter。
5.struts1的action需要继承Action类,struts2的action可以不继承任何类;struts1对同一个路径的所有请求共享一个Action实例,struts2对同一个路径的每个请求分别使用一个独立Action实例对象,所有对于struts2的Action不用考虑线程安全问题。
6.在struts1使用formbean封装请求参数,在struts2直接使用action的属性来封装请求参数。
7.struts1中的多个业务方法放在一个Action中时(即继承DispatchAction时),要么都校验,要么都不校验;对于struts2,可以指定只对某个方法进行校验,当一个Action继承了ActionSupport且在这个类中只编写了validateXxx()方法,那么则只对Xxx()方法进行校验。
(一个请求来了的执行流程进行分析,struts2是自动支持分模块开发,并可以不同模块设置不同的url前缀,这是通过package的namespace来实现的;struts2是支持多种类型的视图;struts2的视图地址可以是动态的,即视图的名称是支持变量方式的,举例,论坛发帖失败后回来还要传递boardid。视图内容显示方面:它的标签用ognl,要el强大很多,在国际化方面支持分模块管理,两个模块用到同样的key,对应不同的消息;)
与Struts1不同,Struts2对用户的每一次请求都会创建一个Action,所以Struts2中的Action是线程安全的。
struts1配置文件中的redirect视图的url不能接受参数,而struts2配置文件中的redirect视图可以接受参数。
(摘自:张孝祥老师java面试宝典)
使用ActionForward优化Struts应用程序
从一个servlet内部,通过运用javax.servlet.RequestDispatcher类的forward方法你就可以将控制流程引导到一个目的资源。在login应用程序的action类中,该代码形式如下:
RequestDispatcher rd = request.getRequestDispatcher(destination); rd.forward(request, response); |
其中destination就是到一个目的资源的路径。
但是在一个典型的Struts应用程序中,你可以用ActionForward类作为替代。运用这个类的好处就是你不再需要创建一个RequestDispatcher对象并调用它的forward方法了。
你可以将ActionForward类用于一个Action类的execute方法中。注意,其中一个重载的execute方法有如下的定义,它返回一个ActionForward对象:
public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception |
因为当时我们还没有讲到ActionForward类,所以在本系列的第一部分和第二部分中所有Action类的execute方法都只返回了空值。现在,在一个Action类的execute方法中,你就可以用ActionForward类来代替下面这个RequestDispatcher对象实例了:
RequestDispatcher rd = request.getRequestDispatcher(destination); rd.forward(request, response); |
新的代码变成:return (new ActionForward(destination));
构建ActionForward对象
ActionForward类提供了下面五种构造器:
public ActionForward() public ActionForward(String path) public ActionForward(String path, boolean redirect) public ActionForward(String name, String path, boolean redirect) public ActionForward(String name, String path, boolean redirect, boolean contextRelative) |
虽然这些构造器是不需要说明的,但我们应该注意下面几点。在这些构造器中,第二种可能是最常用的。后四种构造器中的path参数表示的是到目的资源的路径。后三种构造器中的redirect布尔值表示的是是否执行了一个重定向(redirect)。(缺省情况下,这个值设置为false,因为redirect比forward慢。)最后,第五个构造器中的contextRelative布尔值表示该路径是否应该是context-relative的,而不是module-relative的。
同样,一个ActionForward实例也可以有一个逻辑名称,你可以用这个名称来查找与一个特殊的ActionMapping对象相关的实例。(参见本系列第四部分关于ActionMapping的讲述。)
学习ActionForward类的方法
ActionForward类定义了三个保护字段——name、path和redirect——它们构成了ActionForward的三个属性。ActionForward类提供getter和setter方法来从这些字段读值、给这些字段赋值。这些方法是不需要说明的,定义如下:
public boolean getContextRelative() public void setContextRelative(boolean contextRelative) public String getName() public void setName(String name) public String getPath() public void setPath(String path) public boolean getRedirect() public void setRedirect(boolean redirect) |
除此之外,ActionForward类还重载了toString方法并返回:"ActionForward[" + name + "]"其中name是名称字段。
最后,还有一个freeze方法,它固定了一个组件的配置。
再次运用Login应用程序
要完全了解ActionForward类,我们需要再次运用在本系列第一部分和第二部分构建的login应用程序。你可以下载完整的应用程序,把它重命名为myStrutsApp2。它的web.xml和struts-config.xml文件同myStrutsApp1中的文件是一样的,JSP页面也没有改变。只有action类同以前不同。
注意下面这行代码是新的:return (new ActionForward("/mainMenu.jsp"));
它替代了下面这些代码,现在它们都被注释出来了:
RequestDispatcher rd = request.getRequestDispatcher("/mainMenu.jsp"); rd.forward(request, response); |
同样,下面这些代码也都被重写了:
// RequestDispatcher rd = request.getRequestDispatcher("/login.jsp"); // rd.forward(request, response); |
新的代码变成:return (new ActionForward("/login.jsp"));
ViewSecretAction类
ViewSecretAction也变得更好了。execute方法最后的这三行代码现在由一行来处理了,返回(new ActionForward (“/viewSecret.jsp”)):
//RequestDispatcher rd =request.getRequestDispatcher("/viewSecret.jsp"); //rd.forward(request, response); // return null; |
接下来,我们来重新查看LogoutAction类(见列表3)。注意execute方法中下面这些代码已经被替代了:
// RequestDispatcher rd = request.getRequestDispatcher("/login.jsp"); // rd.forward(request, response); // return null; |
你只需要用下面这一行代码来取代它就行了:return (new ActionForward("/login.jsp"));
ActionForward是个很有用、功能很多的类,它可以让你更简单、更快、更直接地完成许多事情,这可能就是它很受欢迎的原因。在本系列的第四部分,你可以了解另一个重要的类org.apache.struts.action.ActionMapping,它可以使你的代码更有效、更漂亮。
Struts 查看文件内容功能的方法
1.Action 代码
/* * $Id: ShowFileAction.java 471754 2006-11-06 14:55:09Z husted $ * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.struts.webapp.validator; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.InputStream; import java.io.InputStreamReader; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.Log; /** * Action which retrieves a file specified in the parameter * and stores its contents in the request, so that they * can be displayed. */ public class ShowFileAction extends Action { /** Logging Instance. */ private static final Log log = LogFactory.getLog(ShowFileAction.class); public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // Get the file name String fileName = mapping.getParameter(); StringBuffer fileContents = new StringBuffer(); if(fileName != null) { InputStream input = servlet.getServletContext().getResourceAsStream(fileName); if (input == null) { log.warn("File Not Found: "+fileName); } else { InputStreamReader inputReader = new InputStreamReader(input); char[] buffer = new char[1000]; while (true) { int lth = inputReader.read(buffer); if (lth < 0) { break; } else { fileContents.append(buffer, 0, lth); } } } } else { log.error("No file name specified."); } // Store the File contents and name in the Request request.setAttribute("fileName", fileName); request.setAttribute("fileContents", fileContents.toString()); return mapping.findForward("success"); } } |
分析:
String fileName = mapping.getParameter(); |
其中mapping 是ActionMapping 对象,是ActionConfig的子对象。 其中ActionConfig封装了Struts-config.xml 中的配置信息。
inputStream input = servlet.getServletContext().getResourceAsStream(fileName);
每个Web应用程序都是一个独立的Servlet容器,每个Web应用程序分别用一个ServletContext对象。ServletContext对象包含在ServletConfig对象中,
调用ServletConfig.getServletContext()方法获取ServletContext对象。
1、 getResourcePath 返回一个包含该目录和文件路径名称的Set集合
2、 getResource 返回映射到资源上的URL对象。
3、 getResourceAsStream 返回连接到某资源上的InputStream对象
InputStreamReader inputReader = new InputStreamReader(input);
需要重新包装成字符处理。
【2】配置文件
<!-- Show validations.xml --> <action path="/showValidation" type="org.apache.struts.webapp.validator.ShowFileAction" scope="request" parameter="/WEB-INF/validator/validation.xml"> <forward name="success" path="/showFile.jsp" /> </action> |
【3】在JSP页面 读取信息
<!-- Show validations.xml --> <action path="/showValidation" type="org.apache.struts.webapp.validator.ShowFileAction" scope="request" parameter="/WEB-INF/validator/validation.xml"> <forward name="success" path="/showFile.jsp" /> </action> |
bean:write 标签 有个filter属性。如果为true 的话,则表示
将把输出内容中的特殊HTML符号作为普通字符串来显示;如果filter属性为false,则不会把输出内容中的HTML符号转化为普通字符串.
Struts2拦截器execAndWait简介
<action name="register" class="com.abc"> <interceptor-ref name="defaultStack"></interceptor-ref> <interceptor-ref name="execAndWait"> <param name="excludeMethods">input</param> <!-- 等待时间,执行时间没有超过此值,将不显示等待画面 (毫秒) <param name="delay">1000</param>--> <!-- 间隔检查时间,检查后台进程有没有执行完毕,如果完成了它就立刻返回,不用等到等待,用户不会看到等待画面 <param name="delaySleepInterval">50</param>--> </interceptor-ref> </action> @Override public String execute() throws Exception { while(process<total){ process++; Thread.sleep(900); System.out.println(process); } return SUCCESS; } |
<result name="wait">wait.jsp</result> |
<%@page language="java" contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="s"uri="/struts-tags"%> <!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <meta http-equiv="refresh" content="1;url=<s:url includeParams="none" />"/> <title> </title> </head> <body> <h1>数据处理中,请稍等......</h1> process:${process } total:${total } <br> 如果没有自动跳转请<a href="<s:url includeParams="all" />">点这里</a>. 其中的includeParams参数取值为:<br> none,不把参数加入到url参数中<br> all,是把get和post中的参数加入到url参数中<br> get,是只把get中的参数加入到url参数中 </body> </html> |
public interface SessionAware{ public void setSession(Map map); } public abstract class AbsBasicAction extends ActionSupport implements SessionAware{ /** 当前 Session */ protected Map session ; public void setSession(Map session) { this.session = session ; } } |
struts 实例
作为基于MVC模式的Web应用最经典框架,Struts已经正式推出了1.1版本,该版本在以往版本的基础上,提供了许多激动人心的新功能。本文就将带你走进Struts1.1去深入地了解这些功能。
说明:希望本文的读者能有一定的Struts使用基础。
1、Model 2 Struts是基于Model 2之上的,而Model 2是经典的MVC(模型-视图-控制器)模型的Web应用变体,这个改变主要是由于网络应用的特性--HTTP协议的无状态性引起的。
Model 2的目的和MVC一样,也是利用控制器来分离模型和视图,达到一种层间松散耦合的效果,提高系统灵活性、复用性和可维护性。在多数情况下,你可以将Model 2与MVC等同起来。
在利用Model 2之前,我们是把所有的表示逻辑和业务逻辑都集中在一起(比如大杂烩似的JSP),有时也称这种应用模式为Model 1,Model 1的主要缺点就是紧耦合,复用性差以及维护成本高。
2、Struts 1.1 和Model 2
既然Struts 1.1是基于Model 2之上,那它的底层机制也就是MVC,首先,控制器(ActionServlet)进行初始化工作,读取配置文件(struts-config.xml),为不同的Struts模块初始化相应的ModuleConfig对象。比如配置文件中的Action映射定义都保存在ActionConfig集合中。相应地有ControlConfig集合、FormBeanConfig集合、ForwardConfig集合和MessageResourcesConfig集合等。
提示:模块是在Struts1.1中新提出的概念,在稍后的内容中我们将详细介绍,你现在可以简单地把模块看作是一个子系统,它们共同组成整个应用,同时又各自独立。Struts1.1中所有的处理都是在特定模块环境中进行的。模块的提出主要是为了解决Struts1.0中单配置文件的问题。
控制器接收HTTP请求,并从ActionConfig中找出对应于该请求的Action子类,如果没有对应的Action,控制器直接将请求转发给JSP或者静态页面。否则控制器将请求分发至具体Action类进行处理。
在控制器调用具体Action的execute方法之前,ActionForm对象将利用HTTP请求中的参数来填充自己(可选步骤,需要在配置文件中指定)。具体的ActionForm对象应该是ActionForm的子类对象,它其实就是一个JavaBean。
此外,还可以在ActionForm类中调用validate方法来检查请求参数的合法性,并且可以返回一个包含所有错误信息的ActionErrors对象。如果执行成功,ActionForm自动将这些参数信息以JavaBean(一般称之为form bean)的方式保存在Servlet Context中,这样它们就可以被其它Action对象或者JSP调用。
Struts将这些ActionForm的配置信息都放在FormBeanConfig集合中,通过它们Struts能够知道针对某个客户请求是否需要创建相应的ActionForm实例。
Action很简单,一般只包含一个execute方法,它负责执行相应的业务逻辑,如果需要,它也进行相应的数据检查。执行完成之后,返回一个ActionForward对象,控制器通过该ActionForward对象来进行转发工作。
我们主张将获取数据和执行业务逻辑的功能放到具体的JavaBean当中,而Action只负责完成与控制有关的功能。遵循该原则,所以在上图中我将Action对象归为控制器部分。
提示:其实在Struts1.1中,ActionMapping的作用完全可以由ActionConfig来替代,只不过由于它是公共API的一部分以及兼容性的问题得以保留。ActionMapping通过继承ActionConfig来获得与其一致的功能,你可以等同地看待它们。同理,其它例如ActionForward与ForwardConfig的关系也是如此。
3、模块
我们知道,在Struts1.0中,我们只能在web.xml中为ActionServlet指定一个配置文件,这对于我们这些网上的教学例子来说当然没什么问题,但是在实际的应用开发过程中,可能会有些麻烦。因为许多开发人员都可能同时需要修改配置文件,但是配置文件只能同时被一个人修改,这样肯定会造成一定程度上的资源争夺,势必会影响开发效率和引起开发人员的抱怨。Struts 1.1 在Struts 1.1中,为了解决这个并行开发的问题,提出了两种解决方案:
1. 多个配置文件的支持
2. 模块的支持
支持多个配置文件,是指你能够为ActionServlet同时指定多个xml配置文件,文件之间以逗号分隔,比如Struts提供的MailReader演示例子中就采用该种方法。
ActionServlet
这种方法可以很好地解决修改冲突的问题,不同的开发人员可以在不同的配置文件中设置自己的Action、ActionForm等等(当然不是说每个开发人员都需要自己的配置文件,可以按照系统的功能模块进行划分)。
但是,这里还是存在一个潜在的问题,就是可能不同的配置文件之间会产生冲突,因为在ActionServlet初始化的时候这几个文件最终还是需要合并到一起的。比如,在struts-config.xml中配置了一个名为success的,而在struts-config-registration.xml中也配置了一个同样的,那么执行起来就会产生冲突。
为了彻底解决这种冲突,Struts 1.1中引进了模块(Module)的概念。一个模块就是一个独立的子系统,你可以在其中进行任意所需的配置,同时又不必担心和其它的配置文件产生冲突。因为前面我们讲过,ActionServlet是将不同的模块信息保存在不同的ModuleConfig对象中的。要使用模块的功能,需要进行以下的准备工作:
1.为每个模块准备一个配置文件
2.配置web.xml文件,通知控制器
决定采用多个模块以后,你需要将这些信息告诉控制器,这需要在web.xml文件进行配置。下面是一个典型的多模块配置:
要配置多个模块,你需要在原有的一个(在Struts1.1中将其对应的模块称为缺省模块)的基础之上,增加模块对应的。其中表示为config/XXX的形式,其中XXX为对应的模块名,中还是指定模块对应的配置文件。上面这个例子说明该应用有三个模块,分别是缺省模块、customer和order,它们分别对应不同的配置文件。
3、准备各个模块所需的ActionForm、Action和JSP等资源
但是要注意的是,模块的出现也同时带来了一个问题,即如何在不同模块间进行转发?有两种方法可以实现模块间的转发,一种就是在(全局或者本地)中定义,另外一种就是利用org.apache.struts.actions.SwitchAction。
下面就是一个全局的例子:
...
...
path="/moduleB/index.do"
redirect="true"/>
...
...
可以看出,只需要在原有的path属性前加上模块名,同时将contextRelative属性置为true即可。此外,你也可以在中定义一个类似的本地。
name="loginForm"
scope="request"
input="tile.userLogin"
validate="true">
path="/moduleA/login.do"/>
如果你已经处在其他模块,需要转回到缺省模块,那应该类似下面这样定义,即模块名为空。
path="/login.do"/>
此外,你也可以使用org.apache.struts.actions.SwitchAction,例如:
...
...
...
4、ActionServlet
我们首先来了解MVC中的控制器。在Struts1.1中缺省采用ActionServlet类来充当控制器。当然如果ActionServlet不能满足你的需求,你也可以通过继承它来实现自己的类。这可以在/WEB-INF/web.xml中来具体指定。
要掌握ActionServlet,就必须了解它所扮演的角色。首先,ActionServlet表示MVC结构中的控制器部分,它需要完成控制器所需的前端控制及转发请求等职责。其次,ActionServlet被实现为一个专门处理HTTP请求的Servlet,它同时具有servlet的特点
Struts中的MVC
大家都知道,Struts是基于MVC模式的Web应用框架。Struts的优点之一就是将Web应用分成控制,模型和视图。模型中仅包含业务逻辑,视图中仅包含了显示逻辑。当我经过3次基于Struts开发web应用之后,对这一点有了一点感性的认识。
一、模型与视图的独立
所谓模型与视图的独立。实际上,就是要求我们在开发过程中,应该将模型组件和与视图有关的组件(一般是一些javabean)放在两个不同的包里。并且这两个包应该相互之间没有任何依赖关系。具体地讲就是这两个包相互都不能有导入。在视图组件这个包中除了包含javabean(通常用作DTO使用,将数据传向jsp),还应该包含一些键值的常量。因为DTO都是要存放在request范围里的,需要定义一些键值。由于这些键值是与视图密切相关的,所以不能够到处乱放,而是一定要放在视图组件包内。而模型组件包在开发过程中,你要完全抛开Struts和jsp,就当这些完全不存在,这样开发出来的模型组件即使将来换一个界面(例如:Swing)时,就可以很容易的重用。
二、控制的独立
首先,控制部分是由Struts软件提供的。Struts软件当然无法与你开发的视图和模型有依赖关系,因为Struts在开发的时候,你的模型和视图还没有开发出来呢。Strutst提供了Action这个父类,相当于提供了一个接口,所有具体的执行细节都由Action扩展类来实现。这样Struts框架将控制和控制的内容进行类分离,保证了控制与控制的内容(模型和视图)的独立性。 当然,你在开发模型和视图部分时也不要依赖控制部分,即,不要在你的软件包中导入org.apache.struts包及其子包中的类。只有这样才能真正保持MVC之间的独立性。
三、扩展Action类
前两点主要都在谈独立性。但是,一旦讲到扩展Action类,可以说所有的依赖关系都发生在这里。大家都知道,Action扩展类,负责调用模型和选择视图,那么当你在开发这些Action扩展类的时候,就需要导入模型组件包和视图组件包。也有是说Action依赖模型和视图。由于Action扩展类还有继承Action自类。Action类是控制的一部分,因为它位于org.apache.struts.action包中。所以Action扩展类还依赖控制组件。这样看来,Action扩展类仿佛是Struts这个框架中胶水,它依赖模型、视图和控制部分的组件,MVC这三个部分都是通过它来紧密联系在一起的。
四、总结
Struts框架强调MVC的独立,所以在开发时,视图组件、模型组件最好放在一个单独的包中,Action扩展类也放在一个单独的包里。Struts软件包、模型组件包和视图组件包应该相互隔离,彼此没有导入关系。而Action扩展类却依赖所有这三者。Action扩展类仿佛是胶水将MVC联系到了一起。
- 默认分类(20)
- J2EE(25)
- Java(56)
- PHP(55)
- SEO(10)
- 网页设计(20)
- 网站建设(37)
- 数据库(7)
- JavaScript(17)
- JQuery(6)
- MySQL(20)
- SQL Server(6)
- Access(1)
- Oracle(6)
- office(6)
- Dreamweaver(4)
- Photoshop(12)
- Flash(9)
- Fireworks(13)
- CSS(14)
- HTML(4)
- .NET(7)
- ASP(2)
- DB2(1)
- Ajax(2)
- Linux(12)
- Struts(7)
- Hibernate(8)
- Spring(2)
- Jsp(22)
- Asp(8)
- C#(3)
- C++(1)
- 网络安全(5)
- 软件工程(7)
- XML(1)
- English(2)
- 计算机等级考试(2)
- 计算机病毒(4)
- 个人日志(76)
- 互联网(15)
- ActionScript(10)
- Android(3)
- 数据结构与算法(1)
- 游戏策略(3)
- 美文翻译(2)
- 编程开发(19)
- 计算机应用(4)
- 计算机(10)
- Unity3d(6)
- 其他(1)
- egret(1)