Struts2架构中的Commons-fileupload组件应用技术

合集下载

使用struts2及xheditor实现文件、图片上传(支持拖拽上传)

使用struts2及xheditor实现文件、图片上传(支持拖拽上传)

xheditor +struts2 文件上传(一般情况和支持HTML5拖拽上传)1、准备工作Struts2.2.3导入相关jar包Xheditor1.1.4引入jquery和xheditor的js文件2、效果图a) 使用上传图片按钮进行上次b) 将图片进行拖入上传(支持html5的浏览器)3、相关代码a)单纯的使用普通方式上传:如下图:Struts2中Action中的方法:和传统的上传没什么区别,记得写getter和setterXheditor官方要求:返回内容必需是标准的json字符串,结构可以是如下:{"err":"","msg":"200906030521128703.gif"} 或者{"err":"","msg":{"url":"200906030521128703.jpg","localfile":"test.jpg","id":"1"}} 注:若选择结构2,则url变量是必有注意:1.上传成功时返回的json字符串是:{"err":"","msg":"200906030521128703.gif"}2.err是””,不能省略,3.方式1,msg返回值是上传成功文件的路径;4.方式2,则msg中的url是上传成功文件的路径5.url第一个字符是!表示立即上传,不需要点确定就插入到textarea中Jsp中:【特别应该注意的是:html5Upload:false;如果不设置成false,在支持html5的浏览器(eg:chrome)中,会默认使用html5上传的方式,导致未设置multipart/form-data上传失败,而在不支持html5,例如IE中正常。

Struts2返回JSON对象

Struts2返回JSON对象

1、引入包(本文中的包全部引自struts-2.1.8.1\lib):struts2-json-plugin-2.1.8.1.jarjson-lib-2.1.jarcommons-collections-3.2.jarcommons-beanutils-1.7.0.jarcommons-lang-2.3.jarcommons-logging-1.0.4.jarezmorph-1.0.3.jar这7个包是返回json形式的数据必须的。

因为json大量引用了Apache commons的包,所以要加入4个,commons包,除了commons的包外,还需要引入一个ezmorph的包。

最后加入struts2必须的6个包:struts2-core-2.1.8.1.jarxwork-core-2.1.6.jarognl-2.7.3.jarfreemarker-2.3.15.jarcommons-fileupload-1.2.1.jarcommons-io-1.3.2.jar2、后台:1) Userinfo实体类代码public class UserInfo implements Serializable {private int userId;private String userName;private String password;get set方法略}2) Action类public class TestAction extends ActionSupport {private String message; //使用json返回单个值 private UserInfo userInfo; //使用json返回对象 private List userInfosList; //使用josn返回List对象get set方法略/*返回单个值*/public String returnMsg(){this.message = "成功返回单个值";return SUCCESS;}/*返回UserInfo对象*/public String returnUser(){userInfo = new UserInfo();userInfo.setUserId(10000);userInfo.setUserName("刘栋");userInfo.setPassword("123456");return SUCCESS;}/*返回List对象*/public String returnList(){userInfosList = new ArrayList<UserInfo>();UserInfo u1 = new UserInfo();u1.setUserId(10000);u1.setUserName("张三");u1.setPassword("111111");UserInfo u2 = new UserInfo();u2.setUserId(10001);u2.setUserName("李四");u2.setPassword("222222");userInfosList.add(u1);userInfosList.add(u2);return SUCCESS;}}3) struts.xml(必须继承json-default、json-default继承自struts-default)<package name="default" namespace="/json" extends="json-default"><action name="returnMsg" class="com.testAction " method="returnMsg"> <result name="success" type="json"><param name="root">validate</param></result></action><action name="returnUser "class="com.testAction " method="returnUser "><result name="success" type="json"><param name="includeProperties">userInfo\.userId,userInfo\.userName,userInfo\.password</param></result></action><action name="returnList" class="com.testAction "method="returnList"><result name="success" type="json"><param name="includeProperties">userInfosList\[\d+\]\.userName,userInfosList\[\d+\]\.password </param></result></action></package>4、只要继承extends="json-default",result type设置成json之后,容器会把action的属性自动封装到一个json对象中(json拦截器来做)5、includeProperties 参数:输出结果中需要包含的属性值,这里正则表达式和属性名匹配,可以用“,”分割填充多个正则表达式。

struts2+json+jquery实现ajax登录和注册功能

struts2+json+jquery实现ajax登录和注册功能

在上一篇博文中已经学习了如何整合mybatis和spring,实现持久层的CRUD操作、业务层的事务管理和spring的IoC。

现在我们这个demo的基础上,继续整合struts2,并利用json插件和jquery实现ajax,完成后系统将实现登录与注册的简单功能。

浏览器端如何简单、高效地与服务器端进行数据交互是web开发者最为关心的内容。

在客户端构造intput表单数据或者拼凑URL参数名称/参数值,然后在服务器端笨拙地用request.getParameter(“参数名称”)获取参数显然已经过时了,在struts2中,只要在action 里定义了input表单名称/URL参数名称对应的String类型属性,并设置getter和setter 方法,struts2在调用action的时候就可以根据参数值自动帮你设置好action中对应的属性值供你使用,这极大地方便了开发者。

但是json更为强大——它可以根据浏览器端上传的符合格式的数据设置action中对象的值,也就是说,struts2自动封装的数据只有一层,而json是无限层。

json给页面参数的传递带来极大的方便,结合jquery来使用,可以轻易地做到页面局部刷新、页面无跳转进行友好的系统异常提示等,其中后者是我觉得最有必要做到的一点,在action中定义一个message变量,把action方法执行的结果或者系统异常信息放到里面以json的方式返回给客户端,客户端根据这个变量的结果来进行下一步的操作或者提示系统异常信息,非常地好用。

json由javascript中的对象和数组构成,基本形式是{key:value},key为属性名称,value 为属性值,value可以为数字、字符串、数组、对象,value可以为数组和对象是json可以封装无限层数据的关键所在。

至于如何建构和解析json不是本篇博文的详细表述范围,请参考其他资料。

现在就让我们利用struts2作为MVC框架,整合json插件,在浏览器端使用jquery解析和系列化json数据,由此制作一个具有登陆/注册功能的小demo。

Struts S2-045 漏洞调试及分析

Struts S2-045 漏洞调试及分析

Struts S2-045漏洞调试及分析Auth:Cryin’Date:2016.3.9漏洞公告首先看官方给出的漏洞公告信息:“Possible Remote Code Execution when performing file upload based on Jakarta Multipart parser.”问题原因:“It is possible to perform a RCE attack with a malicious Content-Type value. If the Content-Type value isn't valid an exception is thrown which is then used to display an error message to a user.”从公告信息可以得到几个漏洞的重点信息:●存在漏洞的模块是Jakarta●漏洞产生的点是恶意的Content-Type头●恶意的Content-Type头会造成程序抛出异常,在显示错误消息给用户时造成RCE 补丁对比查看Struts2版本2.3.32在github上的commit(Uses default error key if specified key doesn't exist)并对比修改内容:https:///apache/struts/commit/352306493971e7d5a756d61780d57a76eb1 f519a可以看到对LocalizedTextUtil.findText方法进行了重写,并添加了判断。

Struts2RCE漏洞的根本原因是程序将用户可控数据带入OGNL表达式解析并执行,而OGNL(Object Graph Navigation Language)对象图形导航语言是一个功能强大的表达式语言,可以用来获取和设置Java对象的属性,但同时也可以对服务端对象进行修改,绕过沙盒甚至可以执行系统命令。

01、struts2(Struts2开发入门 、常用配置、参数传递) - 副本

01、struts2(Struts2开发入门 、常用配置、参数传递) - 副本

1. Struts2简介1.1. 什么是Struts21.1.1. Struts2的概念Struts2是轻量级的MVC框架,它主要解决了请求分发的问题,重心在于控制层和表现层。

轻量级,指的是Struts2具有较低的侵入性,就是它对我们业务代码的依赖程度很低,简单来说,在使用Struts2框架时,我们的业务代码中基本上不需要import它的包。

Struts2实现了MVC,满足了MVC设计思想。

在我们使用Struts2做开发的时候,就相当于使用了MVC,这是Struts2自动帮助我们实现的,是默认的、隐含的,我们不需要再写特别的代码来实现MVC了。

作为一个框架,Struts2提供了一系列的API,我们可以使用它们来简化代码的编写,从而提升开发效率。

这些API复用程度很高,对业务代码的依赖性也很小,甚至很多是Struts2自动调用的,因此在很大程度上,我们的开发变得可以复用。

Struts2解决请求分发的问题,我们会在后面为什么使用Struts2中讲解。

重心在控制层和表现层,是纵观整个Struts2理论课程来看的,从中我们会体会到这一点,随着大家对Struts2的逐步了解,届时我们再回顾这一点。

1.1.2. 什么是MVCMVC是代码的分层思想,是软件设计领域经典的设计模式。

它根据代码功能的不同,将一个软件的代码分为3部分,即模型、视图、控制器,这3部分代码的含义和功能如下。

1、M-Model 模型模型(Model)的职责是负责业务逻辑。

包含两层:业务数据和业务处理逻辑。

比如实体类、DAO、Service都属于模型层。

2、V-View 视图视图(View)的职责是负责显示界面和用户交互(收集用户信息)。

属于视图的组件是不包含业务逻辑和控制逻辑的JSP。

3、C-Controller 控制器控制器是模型层M和视图层V之间的桥梁,用于控制流程。

比如:在Servlet项目中的单一控制器ActionServlet。

struts2+spring+hibernate整合步骤

struts2+spring+hibernate整合步骤

引用struts2、hibernate、spring所需jar包struts-core-2.x.x.jar ----struts核心包xwork-core-2.x.x.jar -----身体ruts在其撒很难过构建ognl-2.6.x.jar ----对象导航语言freemarker-2.3.x.jar ------struts2的ui标签的模板使用commons-fileupload-1.2.x.jar ----文件上传组件 2.1.6版本后需加入此文件struts-spring-plugin-2.x.x.jar ---用于struts2继承spring的插件hibernate核心安装包下的(下载路径:/ ,点击Hibernate Core 右边的download)hibernate2.jarlib\bytecode\hibernate-cglib-repack-2.1_3.jarlib\required\*.jarhibernate安装包下的(下载路径:/;点击Hibernate Annotations 右边的下载)hibernate-annotations.jarlib\ejb3-persistence.jar、hibernate-commons-annotations.jar hibernate针对JPA的实现包(下载路径:/ ,点击Hibernate Entitymanager右边下载)hibernate-entitymanager.jarlib\test\log4j.jar、 slf4j-log4j12.jarspring安装包下的dist\spring.jarlib\c3p0\c3p0-0.9.1.2.jarlib\aspecti\aspectjweaver.jaraspectjrt.jarlib\colib\cglib-nodep-2.1_3.jarlib\j2ee\common-annotations.jarvlib\log4j\log4j-1.2.15.jarlib\jakarta-commons\commons_loggin.jar数据库驱动包引用创建mysql数据库ssh 设置编码为utf-8 语句:create database ssh character set 'utf8' collate 'utf8_general_ci'引用1.先整合spring和hibernate*将spring和hibernate的jar包放入lib下;*创建spring的beans.xml配置文件Java代码1.<?xml version="1.0" encoding="UTF-8"?>2.<beans xmlns="/schema/beans"3. xmlns:xsi="/2001/XMLSchema-instance"xmlns:context="/schema/context"4. xmlns:aop="/schema/aop"xmlns:tx="/schema/tx"5. xsi:schemaLocation="/schema/beans6./schema/beans/spring-beans-2.5.xsd7. /schema/context8./schema/context/spring-context-2.5.xsd 9. /schema/aop/schema/aop/spring-aop-2.5.xsd10. /schema/tx/schema/tx/spring-tx-2.5.xsd">11.12. <!-- 将bean交由spring管理可以用<bean></bean>和扫描加注 -->13. <!--14. 扫描该包及该包下的子包15. -->16. <context:component-scanbase-package="com.yss"></context:component-scan>17.18.19. <!-- 集成hibernate sessionFactory单例模式线程安全创建耗内存-->20. <!-- 将hibernate的事务也交由spring管理 -->21. <bean id="dataSource"class="boPooledDataSource"22. destroy-method="close">23. <property name="driverClass"value="org.gjt.mm.mysql.Driver" />24. <property name="jdbcUrl"25.value="jdbc:mysql://localhost:3306/ssh?useUnicode=true&amp;characterE ncoding=UTF-8" />26. <property name="user" value="root" />27. <property name="password" value="root" />28. <!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize 之间。

struts2

struts核心 包
加载struts2
要使用struts2,必须在web.xml中进行配置
以过滤器的形式加载 struts2
过滤器所在包: org.apache.struts2. dispatcher.FilterDi spatcher
加载struts2
以过滤器的形式加载struts2
struts2以过滤器的形式加载到工程中,在web.xml中配置: <filter> <filter-name>struts2</filter-name> <filter-class> org.apache.struts2.dispatcher.FilterDispatcher </filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
struts2中的命名空间起到模块化的作用。这个包下 的所有Action(请求的处理类),都应该以: /[命名空间名]/[Action名]来访问 命名空间的名字都应该以“/”开头,如果不配置命名 空间,则默认的就是namespace=“/”。 一个包下不能存在名字相同的Action
struts2常用配置-Action配置
name属性配置Action的名字
class属性配置Action类的完整类路径,说明 用哪个类处理提交的请求。
struts2常用配置-Action配置
LoginAction.java public class LoginAction extends ActionSupport { private String userName; private String password; public void setUserName(String userName) { erName = userName; } public void setPassword(String password) { this.password = password; } public String execute() throws Exception { return SUCCESS; } } 每个请求处理类必须继 承ActionSupport 对应页面表单元素名 对应的表单元素名必须 给出set方法 处理请求的方法。方法 名默认为execute struts2中,所提交的请求 应以.action结尾

Struts2课件

Sturuts2第一节、Struts2介绍Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。

其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大。

Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与Servlet API完全脱离开,所以Struts 2可以理解为WebWork的更新产品。

虽然从Struts 1到Struts 2有着太大的变化,但是相对于WebWork,Struts 2的变化很小。

Struts2对Struts1进行了巨大的改进。

主要表现在如下几个方面: 在Action的实现方面:Struts1要求必须统一扩展自Action类,而Struts2中可以是一个POJO。

线程模型方面:Struts1的Action是单实例的,一个Action的实例处理所有的请求。

Struts2的Action是一个请求对应一个实例(每次请求时都新new出一个对象),没有线程安全方面的问题。

Servlet依赖方面:Struts1的Action依赖于Servlet API,比如Action的execute方法的参数就包括request和response对象。

这使程序难于测试。

Struts2中的Action不再依赖于Servlet API,有利于测试,并且实现TDD。

封装请求参数:Struts1中强制使用ActionForm对象封装请求的参数。

Struts2可以选择使用POJO类来封装请求的参数,或者直接使用Action的属性。

表达式语言方面:Struts1中整合了EL,但是EL对集合和索引的支持不强,Struts2整合了OGNL(Object Graph NavigationLanguage)。

绑定值到视图技术:Struts1使用标准的JSP,Struts2使用"ValueStack"技术。

Struts2知识点详解

Struts 2的基本流程Struts 2框架由3个部分组成:核心控制器FilterDispatcher、业务控制器和用户实现的业务逻辑组件。

在这3个部分里,Struts 2框架提供了核心控制器FilterDispatcher,而用户需要实现业务控制器和业务逻辑组件。

2.核心控制器:FilterDispatcherFilterDispatcher是Struts 2框架的核心控制器,该控制器作为一个Filter运行在Web应用中,它负责拦截所有的用户请求,当用户请求到达时,该Filter会过滤用户请求。

如果用户请求以action结尾,该请求将被转入Struts 2框架处理。

Struts 2框架获得了*.action请求后,将根据*.action请求的前面部分决定调用哪个业务逻辑组件,例如,对于login.action请求,Struts 2调用名为login的Action来处理该请求。

Struts 2应用中的Action都被定义在struts.xml文件中,在该文件中定义Action时,定义了该Action的name属性和class属性,其中name属性决定了该Action处理哪个用户请求,而class属性决定了该Action的实现类。

Struts 2用于处理用户请求的Action实例,并不是用户实现的业务控制器,而是Action代理——因为用户实现的业务控制器并没有与Servlet API耦合,显然无法处理用户请求。

而Struts 2框架提供了系列拦截器,该系列拦截器负责将HttpServletRequest请求中的请求参数解析出来,传入到Action中,并回调Action 的execute方法来处理用户请求。

显然,上面的处理过程是典型的AOP(面向切面编程)处理方式。

图3.19显示了这种处理模型。

图3.19 Struts 2的拦截器和Action从图3.19中可以看出,用户实现的Action类仅仅是Struts 2的Action代理的代理目标。

SSH整合过程(struts-2.3.15.1+spring-3.2.4+hibernate-4.2.3)

SSH整合SSH整合前应该先熟悉各个框架的单独使用,至少要了解各自的xml配置。

环境:struts-2.3.15.1,spring-3.2.4,hibernate-4.2.3,myeclipse10,JDK-1.6,Mysql Jar包:1.新建web项目2.以简单的登录验证为例3.建立login.jsp,login_success.jsp,login_error.jsp4.引入struts2(1)web.xml配置<filter><filter-name>struts2</filter-name><filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepa reAndExecuteFilter</filter-class></filter><filter-mapping><filter-name>struts2</filter-name><url-pattern>/*</url-pattern></filter-mapping>(2)src下的struts.xml配置<package name="default"namespace="/"extends="struts-default"><action name="login"class="com.accp.action.LoginAction" method="login"><result name="success"> /login_success.jsp </result><result name="error"> /login_error.jsp </result></action></package>(3)测试struts2是否能够通过5.引入spring(1)配置web.xml,添加listener<listener><listener-class>org.springframework.web.context.ContextLoaderListener </listener-class></listener><!-- 告知spring config location 的存储位置 --><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:beans.xml</param-value></context-param>(2)配置src下的beans.xml将spring的ApplicationContext.xml拷贝至src下,删除里面的配置项,只保留下面内容<?xml version="1.0"encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans.xsd"></beans>6.引入hibernate(1)配置beans.xml<?xml version="1.0"encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:jee="/schema/jee"xmlns:tx="/schema/tx"xmlns:aop="/schema/aop"xmlns:p="/schema/p"xmlns:util="/schema/util"xmlns:tool="/schema/tool" xmlns:context="/schema/context"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans.xsd /schema/tx/schema/tx/spring-tx.xsd/schema/aop/schema/aop/spring-aop.xsd/schema/jee/schema/jee/spring-jee.xsd/schema/context/schema/context/spring-context.xsd/schema/util/schema/util/spring-util.xsd/schema/tool/schema/tool/spring-tool.xsd"default-lazy-init="true"default-autowire="byName"><!--spring jdbc配置数据源 Mysql--><bean id="dataSource"class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName"value="com.mysql.jdbc.Driver" /><property name="url"value="jdbc:mysql://localhost:3306/test" /><property name="username"value="user"/><property name="password"value="123456"/></bean><!-- hibernate.cfg.xml Spring config --><bean id="sessionFactory"class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"><!-- connection --><property name="dataSource"><ref local="dataSource"/></property><!-- hibernate自身属性 --><property name="hibernateProperties"><props><prop key="hibernate.show_sql">true</prop><prop key="hibernate.format_sql">true</prop><propkey="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <propkey="hibernate.current_session_context_class">thread</prop></props></property><!-- 映射文件<property name="mappingResources"><list><value>com/forwor/ssh/entity/xml/User.hbm.xml</value></list></property>--></bean><!-- 注入 --><bean id="userDao"class="erDaoImpl"> <property name="sessionFactory"><ref local="sessionFactory"/></property></bean><!-- aop --><!-- transaction --><bean id="userManager"class="erManagerImpl"><property name="userDao"><ref local="userDao"/></property></bean><!-- advice --><bean id="transactionManager"class="org.springframework.orm.hibernate4.HibernateTransactionManager "><property name="sessionFactory"><ref local="sessionFactory"/></property></bean><!-- 事务处理 --><bean id="transactionInterceptor"class="org.springframework.transaction.interceptor.TransactionInterce ptor"><property name="transactionManager"><ref local="transactionManager"/></property><property name="transactionAttributes"><props><prop key="register">PROPAGATION_REQUIRED</prop><!--hibernate4必须配置为开启事务否则 getCurrentSession()获取不到--><prop key="get*">PROPAGATION_REQUIRED,readOnly</prop><prop key="find*">PROPAGATION_REQUIRED,readOnly</prop><prop key="select*">PROPAGATION_REQUIRED,readOnly</prop><prop key="query*">PROPAGATION_REQUIRED,readOnly</prop><prop key="sync*">PROPAGATION_REQUIRED</prop><prop key="finish*">PROPAGATION_REQUIRED</prop><prop key="add*">PROPAGATION_REQUIRED</prop><prop key="insert*">PROPAGATION_REQUIRED</prop><prop key="edit*">PROPAGATION_REQUIRED</prop><prop key="update*">PROPAGATION_REQUIRED</prop><prop key="save*">PROPAGATION_REQUIRED</prop><prop key="remove*">PROPAGATION_REQUIRED</prop><prop key="delete*">PROPAGATION_REQUIRED</prop><prop key="login*">PROPAGATION_REQUIRED</prop><propkey="*">PROPAGATION_REQUIRED,ng.Exception</prop></props></property></bean><!-- autoproxy 自动创建代理--><bean id="ProxyCreator"class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyC reator"><property name="beanNames"><list><value>*Manager</value></list></property><property name="interceptorNames"><list><value>transactionInterceptor</value></list></property></bean><bean id="loginAction"class="com.accp.action.LoginAction"scope="prototype"><property name="userManager"><ref local="userManager"/></property></bean></beans>7.类图以用户登录验证为基础的测试流程控制8.注意事项(1)login.jsp 输入内容的name为ername user.password时,LoginAction中应该为user生成相应的get/set方法。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Struts2架构中的Commons-fileupload组件应用技术李静梅;王超宇【摘要】基于HTTP传输协议的Web网页中,采用嵌人Commons-fileupload组件的Struts2框架,实现了文件的上传与下载.利用OGNL表达式提取Session持久层中的文件名,并利用此文件名实现下载文件的动态更名.灵活利用struts2.0自身提供的字段类型,提高下载的鲁棒性.并列举实例体现整合技术和动态文件下载的实用性,最后通过与以往2种常用开发框架的对比数据加以验证说明.【期刊名称】《应用科技》【年(卷),期】2011(038)004【总页数】5页(P39-43)【关键词】上传下载;Struts2架构;Commons-fileupload组件;OGNL表达式【作者】李静梅;王超宇【作者单位】哈尔滨工程大学,计算机科学与技术学院,黑龙江,哈尔滨,150001;哈尔滨工程大学,计算机科学与技术学院,黑龙江,哈尔滨,150001【正文语种】中文【中图分类】TP311.1随着Internet的飞速发展,越来越多的人参与到网络活动中.博客、Email等网络应用如雨后春笋般大量涌现,它们充分利用了现有的网络资源,不仅给人们的生活带来了巨大的方便,同时也正在逐渐影响、改变着人们的日常生活方式.网络应用的大量涌现,使得在Web页面上完成基于HTTP超文本传输协议的上传下载功能显得越来越重要.针对这一问题,近几年科研院所和一部分公司提出了一些行之有效的可行性框架和解决方案.Struts2就是众多框架中的佼佼者.Struts2凭借其良好的扩展性,使其在Web应用中展现出了特有的优势.Common-fileupload是由阿帕奇基金会旗下的java开源社区Jakarta社区开发的一款组件,主要作OGNL expression用是提供文件管理功能.Jakarta社区是一个非常成熟的社区,不仅有着稳定的开发团队,而且参与过Tomcat的研发,因此在利用Tomcat为服务器的网络应用程序中,Common-fileupload组件在速度和稳定性上都具有一定的优势.1 Struts2框架Struts2是Struts系列框架的第2代产品.是在Struts1和WebWork的技术基础上进行了合并,形成的全新的框架.全新的Struts 2框架与Struts1存在着巨大的差别.Struts2大量地借鉴WebWork相关技术,采用拦截器来处理用户的请求,这样的设计降低了框架的耦合性,提高了框架的性能.1.1 Struts2的体系结构Struts2与传统的Struts框架在整个体系结构上有了很大的变化.下面对Struts2的体系机构作下简要的介绍.图1为Struts2的体系结构图.图1 Struts2体系结构利用struts2体系结构展开的工作严格遵循下述开发流程:1)浏览器发送一个请求;2)核心控制器FilterDispatcher根据请求决定调用合适的Action;3)WebWork的拦截器自动对请求应用调用功能,如验证等;4)回调Action的execute方法,该execute方法根据请求的参数来执行一定的操作;5)Action的execute方法处理的结果信息将被输出到浏览器中,支持多种形式的视图.1.2 Struts2中的拦截器Struts2框架以拦截器为所有功能的基础.根据WebWork的中文文档,其解释为——拦截器是动态拦截Action调用的对象.拦截器提供了一种机制,不仅使开发者可以定义一个在action执行前、后执行的代码,而且可以在一个action执行前阻止其执行,同时还能提供一种可以提取action中可重用部分的方法.当请求到达Struts2的拦截器时,Struts2会查找配置文件,并根据其配置文件实例化拦截器的对象,然后串成一个列表(list),最后按照FIFO算法调用列表中的拦截器实例化改对象.2 文件上传2.1 常用上传方式基于HTTP传输协议的文件上传主要有手工上传和框架上传2种方式.采用手工文件上传方式时是由表单元素中的enctype属性决定提交表单的方式,并最终由该属性决定最终是以字符串方式还是以二进制编码方式提交请求.当enctype的值为multipart/formdata时,无法直接通过HttpServletRequest的getParameter方法获取请求参数的值,需要通过二进制流来获取请求内容,从而实现文件的上传.这种传统手工编码方式相当繁琐,因此很少被采用.框架上传方式是将手工上传中的一些可以由计算机自动执行的部分,由框架替程序员完成,这样大大简化了编程,使程序更易于维护和管理.框架中的解释器通过分析HTTP请求中的二进制流,解析出二进制流中所包含的全部表单域,并分析出每个表单域的类型.基于框架的文件上传,允许开发者以简单的方式来取得文件域的内容字节、文件名以及文件内容等信息.目前主流上传下载组件主要有3种,分别是COS、JspSmartUpload和Commons-fileupload.这 3 种组件的最大作用是提供自己的请求解释器,并通过自身提供的解释器解析HTTP请求.Struts2由于其自身优秀的模块化设计,使程序员可以在其上添加任何一种组件,实现自己的不同要求.经过标准测试发现,当采用JspSmartUpload组件进行文件上传时,若上传文件大于200 M,JspSmartUpload自身会因为堆栈溢出而崩溃,给程序带来不可预知的隐患,因此本组件并不适合负载较重、稳定性要求比较高的应用.而COS组件单就性能上来说,要略高于Commons-fileupload,但由于 Struts2与 Commons-fileupload 有更高的契合度,整合较为方便,因此选择后者成为实际上传时所采用的组件. 2.2 基于Commons-fileupload组件的上传Commons-fileupload组件最重要的组成部分是自己提出的请求解释器.Struts2采用拦截器列表实现具体功能,因此并未提出自己的请求解释器.通过上面的分析知道,要利用框架实现文件上传,在程序提出一个上传请求后,Struts2框架本身无法解析这样处理请求,因此文中在实现上传这个功能时的主要贡献就是将Commons-fileupload组件中的请求解释器集成到Struts2.0框架中,通过traditional-API实现整合的方案[1-3].在测试了上述整合方案后,发现利用traditionalAPI实现文件上传占用的内存较多,上传速度较慢.通过阅读官方资料发现common-fileupload组件提供了2种请求解释器,分别是TraditionalAPI 和StreamingAPI这2种方式.经具体测试发现,利用StreamingAPI方式实现上传,能有效降低内存占用量,并能提高上传速度.因此这里采用StreamingAPI解释器实现文件上传.当有multipart/formdata请求时,Struts2.0中的拦截器会将请求拦截下来,并通过配置文件中关于解释器的配置信息,调用Commons-fileupload组件中相应的请求解释器对请求作出分析,通过isFormfiled()方法判断表单是一个普通的表单还是一个文件域,最后将解析出来的信息按照数据流方式传给Struts2框架的拦截器,Struts2将对数据进行进一步的操作.图2 文件上传的过程流程实现文件上传的功能逻辑关系如图2所示.在上述理论指导下,在此按照文件上传功能逻辑关系图进行了实际开发,通过实际程序验证了上述理论.Struts2中的Action并不负责处理HttpServletRequest请求,只是通过拦截器获得文件内容、文件名称和文件类型3个属性值.文件提交到后台时,拦截器通过3个属性值来过滤文件,同时将获得的属性值传递给Commons-fileupLoad组件的解释器,如果程序在完成上述关系图上任何一步出错时,拦截器都会返回错误信息.3 文件下载3.1 利用Stream类型字段解决字符库不匹配问题下载文件时,一般将传输数据的数据类型定义为数据库中的数据类型[4-5],这样的优势是数据不需进行转换就可在前台页面与数据库之间来回传递并显示,降低了编程的难度.但其也存在一个致命的缺陷,就是如果数据库与前台页面字符集不匹配,将造成前台页面显示乱码现象.经过分析与研究发现,在Struts2框架中有一种Stream结果类型,它的本意是处理流类型的数据,例如图片和音乐.通过试验发现只要对数据进行适当的更改,Stream这个字段类型除了可以处理图片、声音等数据外,还可以很好地解决字符库不匹配问题.在提取数据库中数据时,利用 StringBufferInput-Stream函数将数据转换成二进制流信息,然后通过Stream字段将二进制流信息传到程序的前台,在前台利用解析程序将二进制流信息还原成原始信息进行展示.由于采用ASCII码形式传送数据,字符库不匹配问题消弭于无形,大大提高了系统的鲁棒性.3.2 利用OGNL表达式提取session内的文件名OGNL(object-graph navigation language)是一种功能强大的表达式语言,通过表达式语法,可以实现存取对象的任意属性、调用对象的方法、遍历整个对象的结构图、字段类型转化等功能.通过OGNL强大的存取功能,实现了文件下载时的动态更名.当用户点击下载时,后台程序中的OGNL表达式会在整个程序的Session持久层中按照ID号提取文件名,并在调用Windows下载API之前将文件名以动态赋值的方式传给下载API,这样在下载对话框中显示出来的就已经是要下载的文件名,而并非像传统的处理方式那样,在下载完毕后更新文件名.用户可以在下载的过程中直观地了解自己所下载文件的名字.动态文件下载的基本流程如图3所示.图3 实现的下载功能过程流程4 Struts2与2类常用开发框架比较Struts2框架是在Struts1和WebWork的技术基础上进行了合并,形成的全新的框架.在大量吸收原有框架的优点后,Struts 2已经是一个非常具有实用价值的MVC框架.与传统Struts框架相比,Struts2在Action类的实现上更为方便,在线程安全和可测试方面做得都要更好.Struts2相比WebWork来说,不再提供内在的IoC容器支持,转而将Spring作为缺省实现,扬长避短,提高了用户体验,同时Struts2还全面引入了Dojo.5 应用实例测试文件上传下载在工作流引擎中的应用相当广泛,选择一种高效的文件上传下载在工作流引擎中有其重要的实用价值.jBPM(java业务流程管理)是一种基于J2EE的轻量级工作流管理系统,其后成为JBoss企业中间件平台的一个组成部分,改名为JBoss jBPM.以Struts2框架为jBPM开发的工作流引擎,便捷地增加一个文件上传下载模块.整合思想是利用Struts2作为工作流引擎的MVC框架,将Commons-Fileuplod 作为容器,把Struts2的控制与业务逻辑组件相分离.下面是嵌入了Commons-fileUpload组件的Struts2框架关于上传下载应用的配置文件和核心代码:1)Struts.xml配置文件核心代码:上述代码为实现将Commons-fileupload组件中的解释器嵌入到Struts2中的配置文件代码和通过Stream字段类型以二进制流的形式传输数据库内数据的核心代码.下面为了凸显文中提出整合方式的优势,通过标准测试上传了4次大小不同的文件,上传不同大小文件耗时对比结果见表1.表1 不同组件在上传文件时的耗时对比 ms组件名称2 M 20 M 45 M 200 M COS 245 2 391 5 000 53 520 Commons-fileupload 297 3 293 6 700 76 210 JspSmartUpload 536 4 371 8 745堆栈溢出为使对比更直观、明显,这里参照上述数据绘制了具体如图4所示,嵌入不同组件的Struts2框架上传速度对比图.图4 嵌入不同组件的Struts2框架上传速度对比一般系统所要上传下载的文件大小主要集中在2~45 M区间内,但难免有可能会出现上传下载大文件的时候,因此选择上述几个文件大小作为测试上传的测试集[6].根据图4可以看出,上传20 M左右的文件时,采用了Commons-fileupload和COS组件的速度性能相差无几,但是JspSmartUpload与其他2种的差距就已经很明显了,当文件大于200 M时,JspSmartUpload已经因为堆栈溢出而崩溃了.通过表格和对比图可以发现,采用Commons-fileupload组件的系统无论从速度还是稳定性上都比JspSmartUpload组件有很大提高.Commons-fileupload与COS在上传速度与稳定性上差别不大,但是Commons-fileupload比COS更易于整合到Struts2框架中;因此从系统整体的开发效率和性能上来说,Commons-fileupload组件无疑是最佳选择,同时也更适合以业务为主的web环境.6 结束语提出了一种将Commons-fileupload组件嵌入到Struts2中形成的新框架,该框架已成功地应用于多种文件上传下载系统中.通过实际使用证明:带有新元素的Struts2框架,提高了文件上传下载的速度,通过文件动态更名,增加了文件上传下载的实用性.通过实验证明了新框架在文件上传速度和准确率上的优越性.基于Struts2形成的新框架不拘泥于一种文件形式,符合文件上传下载的通用性,有利于文件上传下载功能的推广,具有良好的应用前景.参考文献:[1]WU M.Analytical method for the lateral buckling of the struts in beam string structures[J].Engineering Structures,2008,30(9):2301-2310. [2]SAHOO D K,GAUTERM R K.Strength and deformation characteristics of bottle-shaped struts[J].Magazine of Concrete Research,2008,8(9):137-144.[3]于银山,胡正华.基于Struts2框架的Web应用开发[J].电脑知识与技术,2009,5(16):59-62.[4]段旭光,李岚,董立岩,等.基于HTTP文件上传进度显示组件的设计及实现[J].吉林大学学报:信息科学版,2006,24(1):89-93.[5]李林珊,郑丽娅.基于JXL的数据导入导出处理[J].计算机软件与应用,2008,27(9):95-96.[6]刘锦锦.基于Struts框架的Web网站开发及数据分析[D].北京:北京化工大学,2005.。

相关文档
最新文档