这一篇讲“将选择的图片上传到指定的服务器”。
说实话,这个功能写了好久,一会儿json拼的有问题访问不到后台,一会儿后台又说form表单的enctype不是multipart/form-data类型,各种乱七八糟的问题折腾了一下午都没好,第二天再弄的时候,竟然莫名其妙的好了,而且后来再也没出过问题。真是匪夷所思啊!
好啦,废话说到这里,言归正传。
这里以发布公告为例:输入公告内容,上传需要的图片(也可以不上传),点击“保存”按钮进行数据提交。其中内容能够和图片必须有一项不为空,“保存”按钮触发事件savaAnnounce()。
一、提交数据的代码如下:
/** *该方法用来保存公告 * @param obj:A标签 * **/ function savaAnnounce(obj){ //判断保存是灰色的还是绿色的,若是灰色的不能保存 var opacity = $(obj).css("opacity"); //当前按钮处于置灰状态,不能操作 if((opacity+"")=="0.5") return false; //进行进度条提示 api.showProgress({ title: '数据提交中', modal: false }); //1、获取公告内容 var announceContent = jQuery.trim($("#announceContent").val());//去除左右的空格 var contentLen = announceContent.length; if(contentLen>0){//说明有填写内容,那么校验是否有特殊词汇,若是没有内容不校验 //判断是否有敏感词汇 if(checkStr2(announceContent) || checkStr2(announceContent)){//两个当中有一个有特殊字符 showErrorInfoBySys("内容不允许有特殊字符","1"); return false; } }else{//说明没有数据 announceContent = ""; } //2、获取图片数量 var picLen = $("#picList").children().length; //alert(contentLen+"\n"+picLen); //3、若是内容和图片数量都为0,说明什么都没有填写,那么不能提交数据 if(contentLen<=0 && picLen<=0){ showErrorInfoBySys("请输入内容或上传图片","1"); return false; } //4、处理图片路径信息 var fileList = ""; if(picLen>0){ $("#picList").children().each(function(i){ fileList+=",\"file"+(i+1)+"\":\""+this.children[0].src+"\"";//只显示文件名称 }); //截取掉最开始的逗号 if(fileList.length>1){ fileList = fileList.substring(1); } } fileList = eval('('+("{"+fileList+"}")+')'); //4、提交数据 api.ajax({ url:$api.getStorage("url"), method:'post', dataType:'text', data:{ values:{ 'announceContent':announceContent, 'user_id':$api.getStorage("u_id"), 'user_name':$api.getStorage("u_name"), 'time':new Date().getTime() }, files:fileList } },function(ret, err){ api.hideProgress();//隐藏进度提示框 if (ret) { //跳转到公告列表界面: api.openWin({ name: 'my_notice', url: 'mynotice.html', pageParam:{ 'user_id':$api.getStorage("u_id") }, progress:{ type:"default", title:"玩命加载中..." } }); } else { api.alert(JSON.stringify(err)); } }); } /** *该方法用来显示错误信息-调用系统定时方法 * @param flag:1-隐藏进度提示框 非1:不隐藏 * @param msg:错误信息 * **/ function showErrorInfoBySys(msg,flag){ if((flag+"")=="1"){ api.hideProgress();//隐藏进度提示框 } //显示错误信息 api.toast({ msg: msg, duration: time, location: 'bottom' }); } /**该方法用来判断字符串中是否存在特殊字符-只包括SQL常用关键字 /*true:说明有特殊字符 /*false:说明没有特殊字符 */ function checkStr2(str){ var myReg = new RegExp("(\\b(select|update|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute)\\b)"); if(myReg.test(str)) return true; return false; }
二、后台进行文件上传:
servlet:
String retuStr="提交失败!"; Object result = new com.wjl.dataengine.UploadFile().upload(request, response); if(result instanceof SUser ){//如果是user的子类,说明添加成功 //往数据库中添加日志 addLog((SUser)result,"添加公告"); retuStr="提交成功!"; }else{ retuStr = result.toString();//否则就是错误信息 } response.setCharacterEncoding("UTF-8"); response.setContentType("text/html"); response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Cache-Control", "no-store"); response.setDateHeader("Expires", 0); System.out.println("retuStr:"+retuStr); response.getWriter().write(retuStr); response.getWriter().flush(); response.getWriter().close();
文件上传:
/** * 该方法用来上传文件 * @param request:request请求 * @return Object:若是suer对象说明添加成功,否则返回错误信息 * **/ public Object upload(HttpServletRequest request,final HttpServletResponse response){ Object retuStr="提交失败!"; //1、判断提交上来的数据是否是上传表单的数据 if(!ServletFileUpload.isMultipartContent(request)){//不是上传表单的数据 //按照传统方式获取数据 String announceContent = request.getParameter("announceContent");//公告内容 String user_id = request.getParameter("user_id");//发布人序号 String user_name = request.getParameter("user_name");//发布人 System.out.println("内容:\n"+announceContent); /* try{ String announceContent2 =URLDecoder.decode(announceContent,"utf-8"); announceContent = announceContent2; System.out.println("转码之后的公告内容:"+announceContent); }catch(Exception e){ e.printStackTrace(); } */ if(announceContent==null || announceContent.trim().length()<=0){ return "内容不能为空!"; }else{ result= new com.wjl.ServicesImpl().addAnnounce(announceContent,"",user_id,user_name); if(result.trim().length()<=0){//说明添加成功了 SUser user = new SUser(); user.setS_user_id(Integer.parseInt(user_id)); user.setS_username(user_name); return user; }else{//说明添加失败 return retuStr; } } } //2、处理上传了文件的情况 //得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全 String savePath = getSavePath(); if(savePath.length()<=0){ savePath = request.getRealPath("/")+"upload"; } String year = com.wjl.Time.year().toString();//年份 String month = com.wjl.util.Time.month().toString();//月份 String day = com.wjl.util.Time.date().toString();//日 String tempPathForFile = year+File.separator+month+File.separator+day; String filePath = ""; //上传时生成的临时文件保存目录 String tempPath = getTempPath(); if(tempPath.length()<=0){ tempPath = request.getRealPath("/")+"temp"; } File tmpFile = new File(tempPath); if (!tmpFile.exists()) { //创建临时目录 tmpFile.mkdir(); } try{ //使用Apache文件上传组件处理文件上传步骤: //1、创建一个DiskFileItemFactory工厂 DiskFileItemFactory factory = new DiskFileItemFactory(); //设置工厂的缓冲区的大小,当上传的文件大小超过缓冲区的大小时,就会生成一个临时文件存放到指定的临时目录当中。 factory.setSizeThreshold(1024*100);//设置缓冲区的大小为100KB,如果不指定,那么缓冲区的大小默认是10KB //设置上传时生成的临时文件的保存目录 factory.setRepository(tmpFile); //2、创建一个文件上传解析器 ServletFileUpload upload = new ServletFileUpload(factory); //监听文件上传进度 upload.setProgressListener(new ProgressListener(){ public void update(long pBytesRead, long pContentLength, int arg2) { try { float f = pBytesRead/pContentLength; response.getWriter().write(f+""); } catch (IOException e) { e.printStackTrace(); } } }); //解决上传文件名的中文乱码 upload.setHeaderEncoding("UTF-8"); //设置上传单个文件的大小的最大值,目前是设置为10*1024*1024字节,也就是10MB upload.setFileSizeMax(getFileBufferForSingle()); //设置上传文件总量的最大值,最大值=同时上传的多个文件的大小的最大值的和,目前设置为20MB upload.setSizeMax(getFileBufferFotTotal()); //4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项 List<FileItem> list = upload.parseRequest(request); //获取公告信息 String announceContent = "";//公告内容 String user_id = "";//发布人序号 String user_name = "";//发布人 StringBuffer imgInfo = new StringBuffer();//图片信息 for(FileItem item : list){ //如果fileitem中封装的是普通输入项的数据 if(item.isFormField()){ String name = item.getFieldName().trim(); //解决普通输入项的数据的中文乱码问题 String value = item.getString("UTF-8"); if(value==null || value.trim().length()<=0)value=""; else value = value.trim(); //value = new String(value.getBytes("iso8859-1"),"UTF-8"); //System.out.println("基础信息:\n"+name + "=" + value); //System.out.println("传过来的参数值:"+FieldType.getFileType(name)); switch(FieldType.getFileType(name)){ case ANNOUNCECONTENT:announceContent = value;break; case USER_ID:user_id = value;break; case USER_NAME:user_name = value;break; case TIME:break; default:break; } }else{//如果fileitem中封装的是上传文件 //得到上传的文件名称, String filename = item.getName(); if(filename==null || filename.trim().equals("")){ continue; } //注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如: c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt //处理获取到的上传文件的文件名的路径部分,只保留文件名部分 filename = filename.substring(filename.lastIndexOf("\\")+1); //得到上传文件的扩展名 //String fileExtName = filename.substring(filename.lastIndexOf(".")+1); //如果需要限制上传的文件类型,那么可以通过文件的扩展名来判断上传的文件类型是否合法 //System.out.println("上传的文件名称是:"+filename+"\n上传的文件的扩展名是:"+fileExtName); //获取item中的上传文件的输入流 InputStream in = item.getInputStream(); //得到文件保存的名称 String saveFilename = makeFileName(filename); //得到文件的保存目录 String realSavePath = makePath(saveFilename, tempPathForFile); //拼接图片路径用来保存到数据库 imgInfo.append(","+File.separator+"bfp"+File.separator+realSavePath+File.separator+saveFilename); realSavePath = savePath+File.separator+realSavePath; System.out.println("文件目录:"+realSavePath); //File既可以代表文件也可以代表目录 File file = new File(realSavePath); //如果目录不存在 if(!file.exists()){ //创建目录 file.mkdirs(); } //创建一个文件输出流 FileOutputStream out = new FileOutputStream(realSavePath+File.separator+saveFilename); //创建一个缓冲区 byte buffer[] = new byte[1024]; //判断输入流中的数据是否已经读完的标识 int len = 0; //循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据 while((len=in.read(buffer))>0){ //使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\\" + filename)当中 out.write(buffer, 0, len); } //关闭输入流 in.close(); //关闭输出流 out.close(); //删除处理文件上传时生成的临时文件 item.delete(); //retuStr = "文件上传成功!"; } } String img = ""; if(imgInfo.length()>1){ img = imgInfo.substring(1); }else{img="''";} //往数据库中添加内容 String result=""; result= new com.wjl.ServicesImpl().addAnnounce(announceContent,img,user_id,user_name); if(result.trim().length()<=0){//说明添加成功了 SUser user = new SUser(); user.setS_user_id(Integer.parseInt(user_id)); user.setS_username(user_name); return user; }else{//说明添加失败 return retuStr; } }catch (FileUploadBase.FileSizeLimitExceededException e) { e.printStackTrace(); retuStr="单个文件超出最大值!!!"; }catch (FileUploadBase.SizeLimitExceededException e) { e.printStackTrace(); retuStr="上传文件的总的大小超出限制的最大值!!!"; }catch (Exception e) { retuStr= "文件上传失败!"; e.printStackTrace(); } return retuStr; }
上传代码中用到的一些工具类:
//1、上传的各个参数所在类 public enum FieldType { //规定表单字段 ANNOUNCECONTENT,USER_ID,USER_NAME,TIME; //提供方法用来获取文件类型 public static FieldType getFileType(String fileType){ return valueOf(fileType.toUpperCase()); } } //2、时间操作类: public class Time { public static GregorianCalendar ggcalendar=new GregorianCalendar(Locale.CHINA); /** * 返回当前的年 * @return */ public static Integer year(){ return ggcalendar.get(Calendar.YEAR); } /** * 返回当前月份 * @return */ public static Integer month(){ return ggcalendar.get(Calendar.MONTH)+1; } /** * 返回当前是几号 * @return */ public static Integer date(){ return ggcalendar.get(Calendar.DATE); } } //3、文件操作代码 /** * @Method: makeFileName * @Description: 生成上传文件的文件名,文件名以:uuid+"_"+文件的原始名称 * @param filename 文件的原始名称 * @return uuid+"_"+文件的原始名称 */ private String makeFileName(String filename){ //2.jpg //为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名 return UUID.randomUUID().toString() + "_" + filename; } /** * 为防止一个目录下面出现太多文件,要使用hash算法打散存储 * @Method: makePath * @Description: * @param filename 文件名,要根据文件名生成存储目录 * @param savePath 文件存储路径 * @return 新的存储目录 */ private String makePath(String filename,String savePath){ //得到文件名的hashCode的值,得到的就是filename这个字符串对象在内存中的地址 int hashcode = filename.hashCode(); int dir1 = hashcode&0xf; //0--15 int dir2 = (hashcode&0xf0)>>4; //0-15 //构造新的保存目录 String dir = savePath + "\\" + dir1 + "\\" + dir2; //upload\2\3 upload\3\5 return dir; } /** * 该方法用来获取允许上传的文件总大小 * **/ public long getFileBufferFotTotal(){ long buffer = 200*1024*1024;//文件上传允许最大为200M String fileSize = com.wjl.util.WebAppConfig.app("businessFileSizeForTotal"); if(fileSize!=null){//说明有设置值 fileSize = fileSize.trim(); //有设置值且是数字 if(fileSize.length()>0 && com.wjl.util.Utils.isNumeric(fileSize)){ buffer = Integer.parseInt(fileSize)*1024*1024; } } return buffer; } /** * 该方法用来获取允许上传的单个文件大小 * @return long:配置文件中配置的数据*1024*1024,也就是总共多少M * **/ public long getFileBufferForSingle(){ long buffer = 10*1024*1024;//文件上传允许最大为200M String fileSize = com.wjl.util.WebAppConfig.app("businessFileSize"); if(fileSize!=null){//说明有设置值 fileSize = fileSize.trim(); //有设置值且是数字 if(fileSize.length()>0 && com.wjl.util.Utils.isNumeric(fileSize)){ buffer = Integer.parseInt(fileSize)*1024*1024; } } return buffer; } /** * 该方法用来获取文件保存的路径 * */ public String getSavePath(){ String savePath = com.wjl.util.WebAppConfig.app("businessFilePath"); if(savePath!=null && savePath.trim().length()>0){ savePath = savePath.trim(); }else{ savePath = ""; } return savePath; } /** * 该方法用来获取文件临时保存的路径 * */ public String getTempPath(){ String savePath = com.wjl.util.WebAppConfig.app("businessFileTempPath"); if(savePath!=null && savePath.trim().length()>0){ savePath = savePath.trim(); }else{ savePath = ""; } return savePath; } //4、读取配置文件的类: public final class WebAppConfig { /** * 私有构造方法,不能创建对象 */ private WebAppConfig() { } /*** * * @param key:properties文件中各个选项的name值 * @return String:与name值对应的value值 */ public static String app(String key){ String value=null; if(key!=null && key.trim().length()>0){ Properties prop = new Properties(); //读取指定的文件 InputStream in = WebAppConfig.class.getResourceAsStream("/webApp.properties"); try { prop.load(in); value = prop.getProperty(key).trim(); } catch (IOException e) { e.printStackTrace(); } } return value; } }
相关推荐
APICloud 提供的一款适用于终端/命令行的 APICloud 平台开发工具,基于 apicloud-tools-core 核心开发库 开发,包含新建页面模板,新建应用模板,WiFi同步等核心功能等核心库已有功能。操作系统: Mac/Windows/...
APICloud是一个强大的移动应用开发平台,它允许开发者使用JavaScript语言快速构建原生的iOS和Android应用程序。"APICloud-App-Templates-master.zip"是一个包含APICloud项目的压缩包,其中提供了官方的前端模板,...
在"vue-apiCloud-model-mobile-源码.rar"这个压缩包中,我们可以预见到与使用Vue.js开发移动应用相关的源代码。ApiCloud是一个提供云端一体化服务的平台,它允许开发者通过JavaScript API来构建原生的移动应用。结合...
APICloud studio3基于业界领先的代码编辑器-Vscode深度定制,帮助开发者快速构建多端应用,无论你是面向Android、iOS、Web、App还是小程序打造应用, Studio3都能帮您快速编译对应终端的代码。类AVM语法和扩展API支持...
### APICloud教程:服务器上的页面执行API #### 背景介绍 APICloud作为一款混合开发平台,为开发者提供了高效便捷的应用开发方案。它不仅支持原生接口的调用,还允许开发者通过HTML5、JavaScript等前端技术进行...
在APICloud平台上,开发者可以利用其提供的视频播放模块SDK来构建具有强大视频播放功能的应用程序。这个SDK专为Android Studio设计,便于在apicloud的自定义模块开发中使用。以下将详细介绍APICloud视频播放模块SDK...
Atom 插件: APICloud 语法提示与自动补全支持 Mac/Windows/Linux等主流操作系统是的,第一款同时支持三个主流操作系统的APICloud语法提示插件,现在可以在任意自己喜欢的系统上愉快地编码了!模块智能提示api.require ...
APICloud 为 Atom 编辑器推出的开发工具包。包含新建应用模板,页面模板,WiFi 真机同步,流式日志输出等核心功能。安装Atom编辑器中,搜索并安装 package: apicloud特性支持 Mac/Windows/Linux等主流操作系统;基于...
APICloud studio3是基于业界领先的代码编辑器-Vscode深度定制。无论开发者是开发Android、iOS、Web、App还是小程序, Studio3都能快速编译对应终端的代码。本资源试用windows系统。
四、图片上传 选择图片后,使用`apicloud.file.uploadImage`上传图片到服务器。该方法需要一个参数对象,包含: - localId:本地图片的ID,由`chooseImage`返回。 - serverUrl:服务器接收图片的URL。 - name:上传...
APICloud studio3是基于业界领先的代码编辑器-Vscode深度定制。无论开发者是开发Android、iOS、Web、App还是小程序, Studio3都能快速编译对应终端的代码。本资源试用windows系统。
apicloud-polyfill,是 APICloud 为切实提高前端开发者的混发开发体验而推出的一个脚手架. 借助 apicloud-polyfill ,前端开发者可以直接使用最新的 es6,es7语法,在 JS 层以模块化的方式,高效优雅地开发 APICloud...
报告中列出了与乡创网相关的多个域名,包括apicloud.com的相关子域名,以及微信相关域名如mch.weixin.qq.com和open.weixin.qq.com。所有列出的域名服务器位于中国,分别在浙江省杭州市和北京市。这些域名可能用于...
图片批量上传基于apicloud h5的图片上传,解决状态栏重合,并优化fixStatusBar代码,Android4.4版本以上添加25px,由于原作者删掉博文,放着备份,也方便大家,如果有影响到原作者,烦请私聊我删资源。
蓝牙 , apicloud用于蓝牙扫描,包括Mac , name , uuid
grunt-init-apicloud 基于grunt-init文档开发的一套模板 用于快速开发、部署APICloud应用 基本使用方法 下载模板 git clone https://github.com/taxusyew/grunt-init-apicloud.git ~/.grunt-init/apicloud windows上...
该项目是一款基于APICloud平台的电子设备管理Demo,采用JavaScript、HTML和CSS编写,包含69个文件,其中包括24个JavaScript文件、15个PNG图片文件、9个HTML文件、7个CSS文件、4个GIF动画文件以及相关的文档和资源...
源码可以在APICloud-Studio项目中找到,这是一个很好的学习和定制IDE的机会,特别是对于那些熟悉Java和Eclipse RCP框架的开发者来说。 在功能方面,APICloud Studio提供了丰富的开发工具集,包括代码编辑器、资源...
APICloud-Studio-RCP-Win APICloud提供了一个单一的开源免费HTML编码工具,方便开发者进行应用程序的开发和调试,继承详见APICloud-Studio项目。此为Windows版的APICloud Studio的产品。
APICloud 开发工具核心库,支持新建页面模板,新建应用模板,WiFi同步等核心功能。开发者可基于此核心库,定制各种编辑器插件或者将 APICloud 的开发调试功能与已有的自动化业务流程结合,提升开发效率。特点轻量: ...