Sruts2下实现多文件上传功能(后台上传app软件,做版本更新)
2017-01-21 10:22
681 查看
一:框架信息
只使用了Struts 2框架
二:需要使用的jar包
commons-fileupload.jar
commons-io.jar
如果使用struts2框架自带这2个包,不是使用Struts框架可能需要下载,版本自选,最好选新择版本。
推荐下载网址:
http://download.csdn.net/detail/mxw465508356/7221415#comment
三:JSP页面
首先上传文件、图片、文档、软件之类的在form提交或者ajax提交都需要写enctype=”multipart/form-data”,并且必须是post提交。
enctype类型有
application/x-www-form-urlencoded 在发送前编码所有字符(默认)
multipart/form-data 不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。
text/plain 空格转换为 “+” 加号,但不对特殊字符编码。
JSP代码:
三:后台代码
首先JSP页面上传的是一个文件,已经变成了一种流的形式传入后台,所以其中附带了许多的Input文本框,用普通的方式request.getParameter(“”)是得不到数据的,需要进行特殊处理,需要确定Struts的版本是什么,如果不确定就用以下面的方法进行试试吧。
2.在status2 .3.4.1版本下的struts.xml中的配置方式。其中class改为RequestParseWrapper类的路径就可以了,其他的不用动;蓝色部分就是不同之处。
3.在status2 .3.15版本下的struts.xml中的配置方式。其中class改为RequestParseWrapper类的路径就可以了,其他的不用动
4.在status2 .3.4.1版本和status2 .3.15下的struts.xml中的配置方式,除了标签中name不一样,其他的都一样,一个是struts.multipart.parser;另一个是struts.multipart.handler
可参考网站:https://my.oschina.net/guhai2004/blog/157852
4.在后台的控制器代码中可以加入以下代码
只使用了Struts 2框架
二:需要使用的jar包
commons-fileupload.jar
commons-io.jar
如果使用struts2框架自带这2个包,不是使用Struts框架可能需要下载,版本自选,最好选新择版本。
推荐下载网址:
http://download.csdn.net/detail/mxw465508356/7221415#comment
三:JSP页面
首先上传文件、图片、文档、软件之类的在form提交或者ajax提交都需要写enctype=”multipart/form-data”,并且必须是post提交。
enctype类型有
application/x-www-form-urlencoded 在发送前编码所有字符(默认)
multipart/form-data 不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。
text/plain 空格转换为 “+” 加号,但不对特殊字符编码。
JSP代码:
<form class="am-form" enctype="multipart/form-data" method="post" action="MultiPartServlet/addApp.action"> <table class="am-table am-table-compact am-table-bordered am-text-sm"> <thead> <tr> <th class="am-text-center"> 软件 </th> <th class="am-text-center">添加信息</th> </tr> </thead> <tbody> <tr> <th class="am-text-center">上传软件</th> <th class="am-text-center"> <input class="am-input-sm" type="file" name="upload_app" style="width:550"> </th> </tr> <tr> <th class="am-text-center">上传软件</th> <th class="am-text-center"> <input class="am-input-sm" type="file" name="upload_app" style="width:550"> </th> </tr> <tr> <th class="am-text-center">上传软件</th> <th class="am-text-center"> <input class="am-input-sm" type="file" name="upload_app" style="width:550"> </th> </tr> <tr> <th class="am-text-center">app软件类型</th> <th class="am-text-center"> <select name="coupon_type" class="am-input-sm"> <option value="1">安卓软件</option> <option value="2">苹果软件</option> </select> </th> </tr> <tr> <th class="am-text-center">app类别</th> <th class="am-text-center"> <select name="order_type" class="am-input-sm"> <option value="1">客户端</option> <option value="2">司机端</option> </select> </th> </tr> <tr> <th class="am-text-center">软件版本号</th> <th class="am-text-center"> <input type="text" name="version_number"> </th> </tr> </tbody> </table> <div align="center"> <input class="am-btn am-btn am-btn-primary" type="submit" value="上传" id="subbut" />${errMsg} </div> </form>
三:后台代码
首先JSP页面上传的是一个文件,已经变成了一种流的形式传入后台,所以其中附带了许多的Input文本框,用普通的方式request.getParameter(“”)是得不到数据的,需要进行特殊处理,需要确定Struts的版本是什么,如果不确定就用以下面的方法进行试试吧。
1.首先创建一个类RequestParseWrapper,最好名字就以这个命名,假设这个类是在com.s下面,这个类的方法没有做什么处理,但需要写一个这个类。
package com.s; import java.io.IOException; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest; public class RequestParseWrapper extends JakartaMultiPartRequest{ @Override public void parse(HttpServletRequest servletRequest, String saveDir)throws IOException { } }
2.在status2 .3.4.1版本下的struts.xml中的配置方式。其中class改为RequestParseWrapper类的路径就可以了,其他的不用动;蓝色部分就是不同之处。
<bean type= "org.apache.struts2.dispatcher.multipart.MultiPartRequest" name="myRequestParser" class= "com.s.RequestParseWrapper" scope= "default" optional= "true " /> <constant name= "struts.multipart.handler" value= "myRequestParser" />
3.在status2 .3.15版本下的struts.xml中的配置方式。其中class改为RequestParseWrapper类的路径就可以了,其他的不用动
<bean type= "org.apache.struts2.dispatcher.multipart.MultiPartRequest" name="myRequestParser" class= "com.s.RequestParseWrapper" scope= "default" optional= "true " /> <constant name= "struts.multipart.parser" value= "myRequestParser" />
4.在status2 .3.4.1版本和status2 .3.15下的struts.xml中的配置方式,除了标签中name不一样,其他的都一样,一个是struts.multipart.parser;另一个是struts.multipart.handler
可参考网站:https://my.oschina.net/guhai2004/blog/157852
4.在后台的控制器代码中可以加入以下代码
package com.qt.action; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.servlet.ServletContext; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.lang3.StringUtils; import org.apache.struts2.ServletActionContext; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.ExceptionMapping; import org.apache.struts2.convention.annotation.ExceptionMappings; import org.apache.struts2.convention.annotation.Namespace; import org.apache.struts2.convention.annotation.ParentPackage; import org.apache.struts2.convention.annotation.Result; import org.apache.struts2.convention.annotation.Results; import com.opensymphony.xwork2.ActionContext; import com.qt.bean.appversionbean; import com.qt.util.DBUtil; @ParentPackage("admin-manager") @Namespace("/MultiPartServlet") @Results({ @Result(name = "success", location = "/WEB-INF/jsp/addApp.jsp") }) @ExceptionMappings({ @ExceptionMapping(exception = "java.lange.RuntimeException", result = "error") }) public class addApp extends BaseAction{ private static final long serialVersionUID = -7531145953746024717L; //实体类 public appversionbean m=null; //存放后台输入的数据 Map<String, String> map =new HashMap<String, String>(); //返回的数据 public String errMsg = ""; //定义初始sql为空 String sql =""; //定义变量ii,如果filename获取到了文件名称就会执行ii++,ii就会加一次, //ii=1代表页面在任何一个上传文件框中选择了一个文件, //ii>1代表选择了一个以上的文件进行上传 //ii=0代表页面没有在任何一个上传文件框中选择文件 int ii=0; @Action("addApp") public String requestCount(){ Connection conn = null; PreparedStatement pstmt = null; ResultSet resultSet = null; //判断提交表单的类型是否为multipart/form-data,也可以做为是否为第一次进入这个页面 boolean multipartContent = ServletFileUpload.isMultipartContent(getRequest()); if(!multipartContent) return SUCCESS; try { //这个common-fileupload.jar的类,为后面使用数据使用 DiskFileItemFactory factory=new DiskFileItemFactory(); ServletFileUpload upload=new ServletFileUpload(factory); factory.setSizeThreshold(4096);// 内存存储的最大值 upload.setFileSizeMax(1024*1024*100); // 设置上传的单个文件的最大字节数为100M upload.setSizeMax(1024*1024*1024); //设置整个表单的最大字节数为1G upload.setHeaderEncoding("UTF-8"); //通过该方法可以得到jsp中表单的所有的数据,以流的形式传入,如果该方法得到的是一个null,那可能原因就是struts.xml没有配置正确 List<FileItem> list=upload.parseRequest(getRequest()); //创建2个对象分别存入一样的数据是因为,it1是为了取非file数据,it2是取file数据,如果共用一个对象迭代了一次后再想迭代就不可以了 Iterator<FileItem> it1=list.iterator(); Iterator<FileItem> it2=list.iterator(); //获取普通表单数据存入map集合中 add_input_map(it1); //判断页面普通表单该输入的数据是否输入 if (isDataEmpty(map)) { return SUCCESS; } //获取上传文件的表单数据,普通输入框和上传输入框的的文件都在这里面,需要一个一个的取,上传文件后并填充map值 add_input_file_map(it2); //判断页面是否在文件上传框中选择了上传的文件 if(ii<1){ errMsg = "请选择一个上传文件!"; //上次文件不能为空! return SUCCESS; } //查询出当前数据库最新版本的数据(取最新一条) sql = "SELECT appversion_id,the_server_app_name,app_name,url,version_number,app_state,app_type FROM j_appversion WHERE app_state=? AND app_type=? ORDER BY upload_time DESC LIMIT 1"; conn = DBUtil.getConnection(); pstmt=DBUtil.getPreparedStatement(conn, sql); pstmt.setString(1, map.get("app_state")); pstmt.setString(2, map.get("app_type")); resultSet=pstmt.executeQuery(); if(resultSet.next()){ m=new appversionbean(); m.setAppversion_id(resultSet.getInt(1)); m.setThe_server_app_name(resultSet.getString(2)); m.setApp_name(resultSet.getString(3)); m.setUrl(resultSet.getString(4)); m.setVersion_number(resultSet.getString(5)); m.setApp_state(resultSet.getString(6)); m.setApp_type(resultSet.getString(7)); } //判断数据库中是否有最新上传数据,并且判断当前输入的版本号只能是: 输入的版本号 ==数据库最新版本号+1 //这里的判断是:如果输入的版本号 != 数据库最新版本号+1就进入 if( null!=m && Integer.parseInt(map.get("version_number"))!=(Integer.parseInt(m.getVersion_number())+1)){ errMsg = "请输入正确的版本号,数据库当前版本号是为【"+m.getVersion_number()+"】,你只能输入版本号:"+(Integer.parseInt(m.getVersion_number())+1); return SUCCESS; } //将map数据插入数据库表j_appversion sql = "INSERT INTO j_appversion(j_appversion.the_server_app_name,j_appversion.app_name,j_appversion.url,j_appversion.version_number,j_appversion.app_state,j_appversion.app_type,j_appversion.upload_time) VALUES('" + map.get("the_server_app_name") + "','" + map.get("app_name") + "','" + map.get("url") + "','" + map.get("version_number") + "','" + map.get("app_state") + "','" + map.get("app_type") + "','" + map.get("upload_time") + "')"; pstmt = conn.prepareStatement(sql); pstmt.execute(); errMsg = "上传成功!"; }catch (Exception e) { errMsg = "上传失败!请联系管理员"; return SUCCESS; } finally { DBUtil.closeAll(conn, pstmt, resultSet); } return SUCCESS; } /** * 通过传入的从jsp页面获取到的数据,普通输入框和上传输入框的的文件都在这里面,需要一个一个的取,取出上传文件的数据后上传并填充剩余的map值 * @param it * @param ii * @return * @throws FileNotFoundException * @throws IOException */ public void add_input_file_map(Iterator<FileItem> it) throws FileNotFoundException, IOException { while(it.hasNext()) { FileItem item=(FileItem)it.next();//每一个item就代表一个表单输出项(可能是普通输入框的数据,也可能是上传框的文件) if(!item.isFormField())//判断input是否为普通表单输入项还是上传框的文件,这里item.isFormField()为普通的输入框的数据返回true { //获取文件名称 String filename=item.getName(); if(!StringUtils.isEmpty(filename)){ //进入这个方法代表获取到了上传文件名称,即代表用户选择了上传文件,ii需要加一次 ii++; //截取上传文件的名称的后缀(不带符号小数点".") String prefix=filename.substring(filename.lastIndexOf(".")+1); //得当当前时间格式是:yyyyMMddHHmmss Date currentTime = new Date(); SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss"); String dateString = formatter.format(currentTime); //随机四位数产生(1000-9999的随机数) int random_number=(int)(Math.random()*(9999-1000+1))+1000; //重新对上传文件的名称进行更改,更改规则为:当前时间(年月日时分秒)+四位随机数+文件后缀名(不带符号小数点".") String newfilename=dateString+random_number+"."+prefix; //得到上传文件要写入的目录 ActionContext ac = ActionContext.getContext(); ServletContext sc = (ServletContext) ac.get(ServletActionContext.SERVLET_CONTEXT); String path = sc.getRealPath("/"); System.out.println(path); FileOutputStream out=new FileOutputStream(path+"UploadFileStorage/"+newfilename);//如果文件目录无法自动创建就手动创建 //填充数据库表字段的数据 //1、代表安卓软件;2、代表类型为苹果软件 if("1".equals(map.get("app_state"))){ map.put("app_name", "安卓软件"); }else{ map.put("app_name", "苹果软件"); } //下载路径 map.put("url", "UploadFileStorage/"+newfilename); //上传到服务器上的app软件名称 map.put("the_server_app_name",newfilename); //上传时间(获得当前时间格式yyyy-MM-dd HH:mm:ss) formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String upload_date = formatter.format(currentTime); map.put("upload_time",upload_date); //上传到服务器上的app软件名称 map.put("the_server_app_name",newfilename); //上传文件 InputStream in = item.getInputStream(); byte buffer[] = new byte[1024]; int len = 0; while((len=in.read(buffer))>0){ out.write(buffer,0,len); } in.close(); out.close(); } } } } /** * 获取普通表单数据存入map集合中 * @param it * @throws UnsupportedEncodingException */ public void add_input_map(Iterator<FileItem> it) throws UnsupportedEncodingException { while(it.hasNext()) { FileItem item=(FileItem)it.next();//每一个item就代表一个表单输出项 if(item.isFormField())//判断input是否为普通表单输入项,这里item.isFormField()为普通的输入框的数据返回true { String name=item.getFieldName();//input的name名称 String value= item.getString("UTF-8");//input的value值 //存入页面普通表单输入项的数据 map.put(name, value); System.out.println(name + "=" + value); }else{ } } } private boolean isDataEmpty(Map<String, String> map) { if (StringUtils.isEmpty(map.get("app_state"))){ errMsg = "app软件类型不能为空!"; return true; } if (StringUtils.isEmpty(map.get("app_type"))){ errMsg = "app类别不能为空!"; return true; } if (StringUtils.isEmpty(map.get("version_number"))){ errMsg = "版本号不能为空"; return true; } return false; } }
相关文章推荐
- Android实现APP版本自动更新功能
- android软件更新功能简易实现(未添加版本比较)
- .Net语言 APP开发平台——Smobiler学习日志:快速实现应用中的图片、声音等文件上传功能
- Android通过DownloadManager实现App的版本更新功能
- 通过okhttp3下载文件实现APP版本更新
- Android 轻松实现后台搭建+APP版本更新
- E A S Y 实现文件上传下载【更新版本】
- Android 轻松实现后台搭建+APP版本更新
- android 软件在线版本更新功能的实现
- Android 轻松实现后台搭建+APP版本更新
- 一分钟实现版本更新功能——APP版本更新框架
- Android 轻松实现后台搭建+APP版本更新
- Android 轻松实现后台搭建+APP版本更新
- Android 轻松实现后台搭建+APP版本更新
- Android 轻松实现后台搭建+APP版本更新
- Android app“版本更新”功能的前后端实现
- Android 轻松实现后台搭建+APP版本更新
- Android 轻松实现后台搭建+APP版本更新
- 使用DFSClient实现 hadoop上传文件功能,采用使用输入输出流实现 Hadoop 版本2.7.0
- 使用DFSClient实现 hadoop上传文件功能,采用使用输入输出流实现 Hadoop 版本2.7.0