《个人信息维护》PPT课件.pptx

上传人:tia****nde 文档编号:11499838 上传时间:2020-04-26 格式:PPTX 页数:66 大小:1.19MB
返回 下载 相关 举报
《个人信息维护》PPT课件.pptx_第1页
第1页 / 共66页
《个人信息维护》PPT课件.pptx_第2页
第2页 / 共66页
《个人信息维护》PPT课件.pptx_第3页
第3页 / 共66页
点击查看更多>>
资源描述
S2SH轻量级框架技术-个人信息管理,任务内容(1),任务内容,任务内容(3),表达式语言,EL(ExpressionLanguage)的作用避免(MyType)request.getAttribute()和myBean.getMyProperty()之类的语句,使页面更简洁;支持运算符(如+-*/),比普通的标志具有更高的自由度和更强的功能;简单明了地表达代码逻辑,使用代码更可读与便于维护。,Struts2支持的表达式语言,Struts2支持以下几种表达式语言OGNL(Object-GraphNavigationLanguage),可以方便地操作对象属性的开源表达式语言;JSTL(JSPStandardTagLibrary),JSP2.0集成的标准的表达式语言;Groovy,基于Java平台的动态语言,它具有时下比较流行的动态语言(如Python、Ruby和Smarttalk等)的一些起特性;Velocity,严格来说不是表达式语言,它是一种基于Java的模板匹配引擎,具说其性能要比JSP好。Struts2默认的表达式语言是OGNL是一种表达式语言,通过简单一致的表达式语法,可以存取对象的任意属性。,4.1.3OGNL的优势,支持对象方法调用,如xxx.doSomeSpecial()支持类静态的方法调用和值访问支持赋值操作和表达式串联,如price=100,discount=0.8,calculatePrice(),这个表达式会返回80访问OGNL上下文(OGNLcontext)和ActionContext操作集合对象,OGNL,OGNL是Object-GraphNavigationLanguage的缩写,它是一种功能强大的表达式语言(ExpressionLanguage,简称为EL),通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。现在的Struts2.x中使用OGNL取代原来的EL来做界面数据绑定,所谓界面数据绑定,也就是把界面元素和对象层某个类的某个属性绑定在一起,修改和显示自动同步。和struts1.x的formbean相比,这样做的好处非常明显:在Struts2.x中不需要为每个页面专门写formbean,可以直接利用对象层的对象。如果我们把表达式看做是一个带有语义的字符串,那么OGNL无疑成为了这个语义字符串与Java对象之间沟通的桥梁。,使用OGNL的原因,OGNL称为对象图导航语言。所谓对象图,即以任意一个对象为根,通过OGNL可以访问与这个对象关联的其它对象。示例:,publicclassUserprivateStringusername;privateGroupgroup;publicStringgetUsername()returnusername;publicvoidsetUsername(Stringusername)this.username=username;publicGroupgetGroup()returngroup;publicvoidsetGroup(Groupgroup)this.group=group;,使用OGNL的原因,publicclassGroupprivateStringname;privateOrganizationorg;publicStringgetName()returnname;publicvoidsetName(Stringname)this.name=name;publicOrganizationgetOrg()returnorg;publicvoidsetOrg(Organizationorg)this.org=org;,publicclassOrganizationprivateStringorgId;publicStringgetOrgId()returnorgId;publicvoidsetOrgId(StringorgId)this.orgId=orgId;,使用OGNL的原因,上面三个类,描述了通过一个User对象,可以导航到Group对象,进而导航到Organization对象,以User对象为根,一个对象图如下所示:在真实的环境下,这个对象图可能会极其复杂,但是通过基本的getters方法,都应该能够访问到某个对象的其它关联对象。,User(root)-username-group-name-org-orgId,使用OGNL的原因,下述代码将创建一个User对象,及其相关的一系列对象:如果通过JAVA代码来进行导航(依赖于getters方法),导航到Organization的orgId属性,如下所示:user.getGroup().getOrg().getOrgId();导航的目的,是为了获取某个对象的值或设置某个对象的值或调用某个对象的方法!OGNL表达式语言的真正目的,是为了在那些不能写JAVA代码的地方执行JAVA代码,或者是为了更方便地执行JAVA代码如果使用OGNL表达式来进行导航,导航到Organization的orgId属性,如下所示:user.group.org.orgid可见OGNL表达式最大的优点就是:“简单”和“直观”。,Useruser=newUser();Groupg=newGroup();Organizationo=newOrganization();o.setOrgId(ORGID);g.setOrg(o);user.setGroup(g);,OGNL上下文,Struts2对OGNL作了进一步增强。OGNL表达式的计算都是围绕OGNL上下文来进行的,OGNL上下文实际上就是一个Map对象,由ognl.OgnlContext类(实现了java.util.Map接口)来表示。Struts2把OGNLContext设置为ActionContext,即在Struts2中OGNL上下文(Context)的实现为ActionContext。Struts2把ValueStack作为OGNL的根对象。,OGNL上下文,Struts2中的OGNLContext实现者为ActionContext,它结构示意图如下:当Struts2接受一个请求时,会迅速创建ActionContext,ValueStack,action。然后把action存放进ValueStack,所以action的实例变量可以被OGNL访问。,值栈,在struts2中将OGNL上下文设置为struts2中的ActionContext,并将值栈作为OGNL的根对象。值栈类似于正常的栈,符合后进先出的栈的特点,你可以在值栈中放入、删除和查询对象,值栈是Struts2的核心。OGNL设定的根对象(root对象),在Struts2中就是ValueStack(值栈)。如果要访问根对象(即ValueStack)中对象的属性,则可以省略#命名空间,直接访问该对象的属性即可。,值栈,在struts2中,根对象ValueStack的实现类为OgnlValueStack,该对象不是我们想像的只存放单个值,而是存放一组对象。在OgnlValueStack类里有一个List类型的root变量,就是使用他存放一组对象|-request|-applicationcontext-|-OgnlValueStackroot变量action,OgnlUtil,.|-session|-attr|-parameters在root变量中处于第一位的对象叫栈顶对象。通常我们在OGNL表达式里直接写上属性的名称即可访问root变量里对象的属性,搜索顺序是从栈顶对象开始寻找,如果栈顶对象不存在该属性,就会从第二个对象寻找,如果没有找到就从第三个对象寻找,依次往下访问,直到找到为止。注意:Struts2中,OGNL表达式需要配合Struts标签才可以使用。如:,OGNL的访问,由于ValueStack(值栈)是Struts2中OGNL的根对象,如果用户需要访问值栈中的对象,在JSP页面可以直接通过下面的EL表达式访问ValueStack(值栈)中对象的属性:$foo/获得值栈中某个对象的foo属性如果访问其他Context中的对象,由于他们不是根对象,所以在访问时,需要添加#前缀。application对象:用于访问ServletContext,例如#application.userName或者#applicationuserName,相当于调用ServletContext的getAttribute(username)。session对象:用来访问HttpSession,例如#session.userName或者#sessionuserName,相当于调用session.getAttribute(userName)。request对象:用来访问HttpServletRequest属性(attribute)的Map,例如#request.userName或者#requestuserName,相当于调用request.getAttribute(userName)。parameters对象:用于访问HTTP的请求参数,例如#parameters.userName或者#parametersuserName,相当于调用request.getParameter(username)。attr对象:按page-request-session-application顺序访问其属性。,OGNL基本语法,基本的OGNL语法是十分简单的,当然OGNL支持丰富的表达式,一般情况下,不用担心OGNL的复杂性。例如有一个man对象,该对象有一个name属性,那么使用OGNL来获得该name属性可以使用如下表达式:man.nameOGNL表达式的基础单元称为导航链,简称为链。一个最简单的链由如下部分组成。属性名称方法调用数组元素说明:OGNL表达式基于OGNL上下文中的当前对象,一个“链”将使用上一个“链”的处理结果,开发者可以任意扩展该链的长度,OGNL没有限制。,常量的声明,字符串常量(stringliteral)以单引号或双引号括起来的字符串,例如:HelloWorld和”HelloWorld”.在JAVA中,不能用单引号来界定字符串常量,而在OGNL中是可以的。不过特别要注意的是:如果是单个字符的字符串常量,则必须使用双引号来界定,例如:“S”。OGNL的字符串也支持转义序列,例如:要在JSP页面中输出”Yousaid,”HelloWorld”.”,那么可以使用标签,如下:注意:不要忽略了用于界定整个常量字符串的单引号。如果没有写单引号,那么整个字符串将不会被看成是字符串常量,而是被当作根对象的属性名,从而导致错误。字符常量(Characterliteral)以单引号括起来的字符。例如,H。注意,不能使用双引号,否则将被看成是字符串常量。数值常量(Numericliteral)除了Java中的int,long,float,double外,OGNL还让你用“B”或“b”后缀指定BigDecimal常量,用“H”或”h”后缀指定BigInteger常量,例如,123(int常量),123l(long常量),123.35f(float常量),123b(BigDecimal常量),123h(BigInteger常量)。布尔常量(Booleanliteral)true和falsenull常量(nullliteral).,OGNL操作符,OGNL支持所有的Java操作符(+、-、*、/、+、-、=、!=、=等)与Java类似,并提供了一些特有的操作符。与Java相同的操作符不再介绍,下面看一下OGNL特有的操作符。逗号(,)或序列操作符OGNL的逗号操作符是从C语言中借鉴而来的。逗号被用于分隔两个或多个独立的表达式,整个表达式是最后一个表达式的值。如:team2.person.name,team1.teamname第一个表达式team2.person.name和第二个表达式team1.teamname,整个表达式的值是第二个表达式的值。花括号()操作符花括号()操作符用于创建列表。使用花括号将元素括起来,元素之间使用逗号分隔,例如:“zhangsan”,“lishi”,“wangwu”1此表达式创建了带有三个元素的列表,并且访问其中第二个元素。in和notin操作符in和notin用于判断一个值是否属于一个集合中。如:teamnameinteam1,team2,OGNL表达式,访问属性访问方法访问静态属性和方法访问构造方法访问数组访问集合投影、选择(?$)Lambda:,访问属性,访问属性:访问对象属性(get和set):访问对象属性(get和set):,访问方法,访问类对象的方法:访问action的方法:,访问静态属性和方法,OGNL支持调用类中的静态方法和静态字段,可以使用如下语法格式:其中class必顺给出完整的类名。例如:java.lang.StringvalueOf(5)。如果省略class,那么默认使用类是java.lang.Math,classmethod(args)/调用静态方法classfield/访问静态字段(public权限),访问静态方法:访问静态属性:访问Math静态方法:,访问构造方法,访问构造方法:,访问集合和数组,OGNL的集合操作如果需要一个集合元素的时候(例如List对象或者Map对象),可以使用OGNL中同集合相关的表达式。可以使用如下代码直接生成一个List对象:该OGNL表达式中,直接生成了一个List对象,该List对象中包含3个元素:e1、e2和e3。如果需要更多的元素,可以按照这样的格式定义多个元素,多个元素之间使用逗号隔开。如下代码可以直接生成一个Map对象:Map类型的集合对象,使用key-value格式定义,每个key-value元素使用冒号标识,多个元素之间使用逗号隔开。对于集合类型,OGNL表达式可以使用in和notin两个元素符号。其中,in表达式用来判断某个元素是否在指定的集合对象中;notin判断某个元素是否不在指定的集合对象中,如代码所示。,e1,e2,e3,e1,e2,e3,#key1:value1,key2:value2,访问集合和数组,访问List:访问List中某个元素:访问List中元素某个属性的集合:访问List中元素某个属性的集合中的特定值:|访问Set:访问Set中某个元素:访问Map:访问Map中某个元素:|访问Map中所有的key:访问Map中所有的value:访问容器的大小:,访问集合和数组,集合的伪属性OGNL能够引用集合的一些特殊的属性,这些属性并不是JavaBeans模式,例如size(),length()等等.当表达式引用这些属性时,OGNL会调用相应的方法,这就是伪属性.,投影(Projection),OGNL提供了一种简单的方式在一个集合中对每一个元素调用相同的方法,或者抽取相同的属性,并将结果保存为一个新的集合,称之为投影。假如employees是一个包含了employee对象的列表,那么:在投影期间,使用#this变量来引用迭代中的当前元素。OGNL提供了一种简单的方式来使用表达式从集合中选择某些元素,并将结果保存到新的集合中,称为选择。,#employees.name/返回所有雇员的名字的列表,objects.#thisinstanceofString?#this:#this.toString(),#employees.?#this.salary3000将返回薪水大于3000的所有雇员的列表。#employees.#this.salary3000将返回第一个薪水大于3000的雇员的列表。#employees.$#this.salary3000将返回最后一个薪水大于3000的雇员的列表。,投影(Projection),OGNL表达式符号,struts2OGNL中的#、%和$符号用法说明#符号的用途一般有三种访问非根对象属性,例如示例中的#session.msg表达式,#相当于ActionContext.getContext()用于过滤和投影(projecting)集合,如persons.?#this.age30用来构造Map,例如:#0:男,1:女%符号%符号的用途是在标志的属性为字符串类型时,计算OGNL表达式的值。如下面的代码所示:$符号主要在配置文件(包括国际化文件)中,如在Struts.xml的结果类型上。/test.jsp?id=$userid,不使用:使用:,N语法,所谓N语法,指从位置N开始取值。即使用N.xxx(N是从0开始的整数)这样的语法来指定从哪一个位置开始向下查找对象的属性。表达式1.name访问的就是employee对象的name属性。,N语法,在使用N.xxx语法时,要注意位置序号的含义,它并不是表示“获取栈中索引为N的对象”,而是截取从位置N开始的部分栈。假设栈中有三个对象:Object0,Object1和Object2都有name属性,如下图所示:表达式name访问的是Object0的name属性,在,而1.name访问的则是Object2的name属性,因为1是一个包含了Object1和Object2的部分栈,而且只有Object2有name属性。,top关键字,top用于获取栈顶的对象.对于上张PPT所示的栈,表达式top获取的就是Object0这个对象本身,结合N.xxx语法,我们就可以获取栈中任意位置的对象。例如:0.top获取Object0(等同于top),1.top获取Object12.top获取Object2,2.top.name访问Object2中的name属性,类型转换的原因,客户端浏览器只能将字符串传送到服务器(文件上传除外),而服务器端java语言是强类型语言,数据类型非常丰富,这就造成B/S两端的类型不兼容问题.传统做法:将客户端数据转变成intintv=Integer.parseInt(request.getParameter(“user”);缺陷:过程烦琐枯燥.,类型转换的概念,所有页面与控制器传递的数据均为String类型,而我们在对其进行处理时可能会用到各种数据类型,程序无法自动完成数据类型的转换,需要我们在代码中手动完成,这个过程称为类型转换。,Struts2的内置类型转换器,Struts2提供了强有力的表现层类型转换机制,无需程序员过多干预即可自动完成转换.Struts能自动处理类型转换过程中出现的未知异常.Struts2提供的自动类型转换,包括如下几种类型:,boolean和Boolean:完成String和布尔型之间的转换。char和Character:完成String和字符型之间的转换。int和Integer:完成String和整型之间的转换。long和Long:完成String和长整型之间的转换。float和Float:完成String和单精度浮点型之间的转换。double和Double:完成String和双精度浮点型之间的转换。Date:完成String和日期类型之间的转换,日期格式为用户请求本地的SHORT格式。数组:该类型在数据转换时,必须满足需要转换的数据中每一个元素都能转换成数组的类型。但若程序员自定义类型转换器,则要根据情况判断。集合:在使用集合类型转换器时,如果集合中的数据无法确定,可以先将其封装到一个String类型的集合中,然后在用到某个元素时再进行手动转换。类型转换是在页面与Action相互传递数据时发生的。,内置类型转换器对集合的支持,对List集合的支持:对Map集合的支持:,privateArrayListlist;,privateHashMapmap;,或,空值属性处理,如果属性声明为Collection或List,将自动创建ArrayList对象如果属性声明为Map,将自动创建HashMap对象如果属性是一个具有无参构造方法的bean,将使用ObjectFactory的buildBean()方法创建bean的实例,类型转换错误处理,对于前面的转换器,如果用户在界面上输入一些格式不正确的数据。如:当我们在页面上输入2009/1/1,而我们需要的日期格式是2009-1-1。对于这种情况类型转换器中会因为类型不符合导致错误的发生。当发生了类型转换错误后,Struts2会将转换错误放到ActionContext中一个名为conversionErrors的Map对象中。在出现类型转换错误后,你可以选择是否向用户提示转换错误。在Struts2中有两个拦截器负责处理类型转换错误,如下:com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor此拦截器将conversionErrorsMap中找到的所有错误都添加为action的字段错误(需要实现ValidationAware接口,ActionSupport实现了此接口)。org.apache.struts2.interceptor.StrutsConversionErrorInterceptorStrutsConversionErrorInterceptor只在字段值不是null、不是”或者$“”(表示只有一个空字符串元素的字符串数组)的情况下,把转换错误从ActionContext添加到action的字段错误。注意:在struts-default.xml文件中定义了conversionError拦截器,类型是StrutsConversionErrorInterceptor,这个拦截器已被包含在defaultStack拦截器栈中。(当发生转换错误后,struts2会自动转找input结果视图,所以需要在action的配置中添加input结果映射),类型转换错误处理,总结一下:要向用户报告类型错误,需要实现下面三个步骤:1、引用defaultStack拦截器栈(包含了conversionError拦截器)2、让Action类从ActionSupport继承(实现了ValidationAware接口)3、为Action配置添加input结果映射可以通过xwork.default.invalid.fieldvalue属性自定义错误消息,类型转换错误处理,输出错误信息可以使用fielderror标签来输出字段的错误信息。当填写内容格式不正确时会在页面上出现Invalidfieldvalueforfield“xxx.xxx”,很显然这不是我们想要的,我们自定义错误信息,步骤如下:1、在src下新建资源属性文件夹ApplicationResources.properties,并添加下列内容:xwork.default.invalid.fieldvalue=字段”0”的值无效。在输出类型转换错误消息时,占位符0将自动被字段名所替换。2、编辑struts.xml文件,使用struts.custom.i18n.resources属性设置默认的资源包,如下所示:I18N消息键xwork.default.invalid.fieldvalue对所有字段的类型转换错误都适用,如果你想为某个特定字段定制错误消息,则可以在Action相关的资源文件中添加I18N消息键invalid.fieldvalue.xxx来指定错误消息,xxx是字段名称。资源文件的组织和加载顺序可以I18N章节。例如:在com.neusoft.action.LoginAction相应的包新建LoginAction.properties文件,并添加下列内容:invalid.fieldvalue.user.birthday=无效字段值或者在com.neusoft.vo.User相应的包中新建User.properties文件,并添加下列内容:invalid.fieldvalue.birthday=无效字段值,标签的应用,作用:用来格式化显示日期的格式。它可以用一种你指定的格式来显示(如:“yyyy-MM-dd”),可以生成通俗易懂的注释(如:in2hours,14minutes),或者用预先定义的一个格式来显示(如在properties配置文件中配置struts.date.format).如果没有找到这个struts.date.format,则会找默认的DateFormat.MEDIUM来格式化你的日期对象。当然如果在值栈中没有找你对应的日期对象,则会返回空格。,标签的应用,可配置的标签属性有:nameniceformat,标签的应用,Ongl表达式与标签的应用,Struts2文件上传概述,文件的上传和下载是Web应用中常用的功能。一般情况下可以通过二进制编码的方式来获得请求参数的值,从而通过二进制流来获得上传文件内容。这种手动编程方式比较麻烦,需要手动地控制二进制流,相当的复杂。不过可以使用其他开源组织提供的上传项目,通过这些项目可以非常简单的完成文件上传。,Struts2文件上传概述,表单enctype属性application/x-www-form-urlencoded:默认值,只要是能输出网页的服务器端环境都可以multipart/form-data:上传二进制数据,只有使用multipart/form-data,才能完整的传递文件数据,进行上传操作两个上传框架Common-FileUplaod:apache的开源项目,由jakarta项目组开发。功能强大,简单易用,可以实现一次上传一个或多个文件,并可限制文件大小。COS:OReilly公司开发的开源框架会不定期的增加一些新功能。,Struts2文件上传概述,下载Common-FileUplaod框架地址:http:/jakarta.apache.org/commons/fileupload/下载commons-fileupload-1.2-bin.zip文件解压后得到commons-fileupload-1.2.jarhttp:/jakarta.apache.org/commons/io/下载commons-io-1.3.2-bin.zip文件解压后得到commons-io-1.3.2.jar,Struts2单文件上传,步骤:第一步:在WEB-INF/lib下加入commons-fileupload-1.2.1.jar、commons-io-1.3.2.jar。第二步:把form表的enctype设置为:“multipart/form-data“,如下:,Struts2单文件上传,第三步:在Action类中添加以下属性,属性红色部分对应于表单中文件字段的名称:,publicclassHelloWorldActionprivateFileuploadImage;/得到上传的文件privateStringuploadImageContentType;/得到文件的类型privateStringuploadImageFileName;/得到文件的名称/这里略省了属性的getter/setter方法publicStringupload()throwsExceptionStringrealpath=ServletActionContext.getServletContext().getRealPath(/images);Filefile=newFile(realpath);if(!file.exists()file.mkdirs();FileUtils.copyFile(uploadImage,newFile(file,uploadImageFileName);returnsuccess;,Struts2单文件上传,如果上传文件大于2M时,在页面上就出现了一堆英文的错误信息,大致是:therequestwasrejectedbecauseitssize.exceedstheconfiguredmaximum.解决方法如下:在struts.xml中,添加常量struts.multipart.maxSize,重新设置此常量值,此常量默认为2M。,Struts2多文件上传,步骤:第一步:在WEB-INF/lib下加入commons-fileupload-1.2.1.jar、commons-io-1.3.2.jar。这两个文件可以从http:/commons.apache.org/下载。第二步:把form表的enctype设置为:“multipart/form-data“,如下:,项目中提交用户头像应用,Struts2多文件上传,第三步:在Action类中添加以下属性,属性红色部分对应于表单中文件字段的名称:,publicclassHelloWorldActionprivateFileuploadImages;/得到上传的文件privateStringuploadImagesContentType;/得到文件的类型privateStringuploadImagesFileName;/得到文件的名称/这里略省了属性的getter/setter方法publicStringupload()throwsExceptionStringrealpath=ServletActionContext.getServletContext().getRealPath(/images);Filefile=newFile(realpath);if(!file.exists()file.mkdirs();for(inti=0;iuploadImages.length;i+)FileuploadImage=uploadImagesi;FileUtils.copyFile(uploadImage,newFile(file,uploadImagesFileNamei);returnsuccess;,Struts2文件下载概述,通过Struts2的文件下载支持可以轻松地完成文件下载,而且还可以实现中文文件名下载。通过Struts2文件下载支持与拦截器相结合可以实现文件的下载权限控制。程序下载也非常简单,只需要按照如下的方式设置三个报头域就可以了:Content-Type:application/x-msdownloadContent-Disposition:attachment;filename=downloadfileContent-Length:filesize浏览器在接收到上述的报头信息后,就会弹出文件下载对话框,让你将文件保存到本地硬盘。,Struts2文件下载概述,Struts2通过org.apache.struts2.dispatcher.StreamResult结果类型来支持文件下载,使得原本编写就简单的下载程序变得更加简单了。StreamResult结果类型利用HttpServletResponse对象返回的ServletOutputStream对象向客户端输出下载文件的二进制数据,它有下列参数:,contentType:发送给Web浏览器的数据流的MIME类型(默认是text/plain),即下载文件内容类型contentLength:数据流的长度,以字节为单位(浏览器显示一个进度栏),即下载文件的长度。contentDisposition:用于控制文件下载的一些信息,可选择的设置包括:inline;filename=“下载文件名”和attachment;filename=“下载文件名”,filename指定下载的文件名。Inline表示下载文件在本页面内部打开,attachement表示弹出”文件下载”对话框。不过,这也不是绝对的,对于浏览器能够显示的下载文件是这样的,对于浏览器不支持的下载类型,即使使用inline选项,仍然会弹出”文件下载”对话框。contentDisposition的默认值是inline.inputName:Action中用来下载文件的属性的名字,该属性的类型是InputStream.默认值是inputStream.bufferSize:文件数据从输入复制到输出的缓冲区的大小,默认为1024字节。,Struts2文件下载概述,streamResult结果类型已经在struts-default文件中定义,逻辑名为stream.我们看一个使用stream结果类型的例子:,Struts2文件下载示例,8.2.2Struts2文件下载示例,Struts2文件下载示例,页面download.jsp,Struts2文件下载示例,注意:如果你要下载任意目录下的文件(而不仅限于Web应用程序目录),那么只需要修改action中返回文件输入流的方式即可,例如:returnnewFileInputStream(inputPath).在实际应用中,下载的文件不应该在struts.xml中配置,如果是这样,那就等于将DownloadAction的功能限制为了只下载一个文件。下载文件的选取应该通过编码来实现,根据浏览器传来的下载请求,查询配置文件或数据库,获取真实下载文件数据,构造InputStream对象。,改进文件下载示例,对于下载的文件名、下载的文件类型都是在struts.xml文件中配置的,如果有许多不同类型的文件要提供给用户下载,那么这种方式显然有失灵活性。为了能动态设置文件类型和下载的文件名,我们可以编写一个拦截器,在Action执行完毕,result执行之前,动态添加StreamResult的参数。为了能够在result执行之前截获调用,我们需要用到PreResultListener,该接口可以通过ActionInvocation注册,在Action执行完毕,result执行之前得到一个回调。PreResultListener需要在拦截器中进行注册,所以我们需要编写一个拦截器,然后在拦截器方法中注册一个PreResultListener实例。,改进文件下载示例,改进文件下载示例,说明:在上面的代码中,我们定义了一个匿名的内部类实现PreResultListener接口,然后调用ActionInvocation的addPreResultListener方法注册PreResultListener实例。在匿名内部类的beforeResult()方法中,不能通过invocation.getResult()来得到Result对象,因为此时Result对象还没有被创建,为null.为了修改传递给StreamResult的参数,可以通过如下的方法调用来得到Result的配置信息,Result的配置封装在ResultConfig对象中。向ResultConfig对象添加参数,可以在这个对象上调用addParam()方法。,改进文件下载示例,
展开阅读全文
相关资源
相关搜索

当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!