java之文件上传二(源码)
来源:互联网 发布:网络信号增强器 编辑:程序博客网 时间:2024/05/04 11:05
基础知识在前面一篇,文件上传代码。耐心看到后面的重构,简洁多了
重构代码下载:http://download.csdn.net/detail/xiaozhegaa/9782629
(一) 开发思路:代码看起来有点乱,但是是有思路的
1:工厂–>对象设计模式。创建工厂—–>设置一下工厂的属性,其中涉及了临时文件,那么在源码第一二行先取得上传的真实路径和临时路径
2:得到对象,先设置上传文件的字符编码问题,然后判断是否是MIME协议提交
> 3.1:若不是MIME协议提交,抛异常,提示说要用MIME提交,若不然就收集不到数据哦
>> 3.2 : 若是MIME协议提交,则要把上传的内容转化成FileItemList。也就是用parseRequest()
4:取到list集合之后,循环遍历,判断是否是普通字段
>> 5:如果是普通字段的话,那么采用一般的bean装在就可以 //user.getUsername(“xxx”)
> > 6:否则就文件字段,那么对文件进行处理
7:这是扩展的功能:各种if
>>7.1 :if(fileItem.endWith(“jpg”)) //上传是jpg,给不给通过
>>7.2 :if(fileItem.getSize()==0) //空文件,给不给通过,还是抛异常
> >7.3 :if(fileItem.gizeSize() > 1024 * 200) //文件大于200k,给不给通过
> >7.4 :………等等
8:然后就读写数据,is.readLine(),os.write()。java基础固定写法
9:删除临时文件
10:显示上传成功页面
public class UploadServlet2 extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //取得上传的真实路径和临时路径 String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp"); String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload"); //使用第一个类u //创建上传文件的工厂 DiskFileItemFactory fileItemFactory = new DiskFileItemFactory(); //设置内存中的缓冲区大小。10k fileItemFactory.setSizeThreshold(1024*10); //设置上传文件临时存放的目录 fileItemFactory.setRepository(new File(tempPath)); //使用第二个类 //创建上传文件的对象 ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory); //设置上传文件名字的字符编码 servletFileUpload.setHeaderEncoding("UTF-8"); //判断客户端是否是采用那个了mime协议去上传文件 boolean flag = servletFileUpload.isMultipartContent(request); if(!flag){ //也就是不是采用mime的协议上传文件,那么抛异常。这里也可以采用一般的方式去处理哦哦 throw new ServletException(); }else{ /*也就是说是采用了MIME的协议上传文件 * 解析request中的所有上传内容,并且把每个内容解析成fileItem对象 * fileItem代表的是普通字段跟文件字段两类 */ try { //使用第三个类 List<FileItem> fileItemList = servletFileUpload.parseRequest(request); for(FileItem fileIem :fileItemList){ if(fileIem.isFormField()){ //如果说是普通的字段 String fileName = fileIem.getFieldName(); String fileValue = fileIem.getString("UTF-8"); System.out.println(fileName+"-----"+fileValue); }else{ //这里是文件上传字段 String realFileName = fileIem.getName(); /* * 对于ie浏览器的话上传路径是C:\Users\admin\Desktop\1.jpg, * 而对于一些高级浏览器火狐之类的路径是1.jpg。 因此要对路径做一个处理。只需要1.jsp就可以 */ int index = realFileName.lastIndexOf("\\"); if(index>=0){ //确实是ie浏览器 realFileName = realFileName.substring(index+1); } //通过真实的文件名换算出一个唯一的一个文件名 String makeUuidFileName = makeUuidFileName(realFileName); //通过位运算换算出upload文件夹下面的子文件夹 String makeUuidFilePath = makeUuidFilePath(uploadPath,makeUuidFileName); /* *在读取文件之前可以先进行一系列判断,如果判断不通过,不给提交 *例如 */ //如果无上传文件 if(fileItem.getSize()==0){ throw new NoUpfileException(); } //只能上传JPG文件 if(!realFileName.endsWith("JPG")){ throw new UpfileTypeException(); } //只有上传<=200K的文件 if(fileItem.getSize() > 200 * 1024){ throw new UpfileSizeException(); } //等等各种限制条件,自己写 //获得到文件输入流 InputStream is = fileIem.getInputStream(); //取得文件输出流 OutputStream os = new FileOutputStream(makeUuidFilePath+"/"+makeUuidFileName); byte[] buf = new byte[1024]; int len = 0; while((len = is.read(buf)) > 0 ){ os.write(buf, 0, len);; } is.close(); os.close(); //将上传文件的临时文件删除 fileIem.delete(); request.setAttribute("message", "上传成功"); request.getRequestDispatcher("/WEB-INF/message.jsp").forward(request, response); } } } catch (FileUploadException e) { e.printStackTrace(); request.setAttribute("message","上传文件失败"); request.getRequestDispatcher("/WEB-INF/message.jsp").forward(request,response); } } } /** *这个是防止说一个目录文件过多,采用&方式去推出二级目录之类的函数 */ private String makeUuidFilePath(String uploadPath, String makeUuidFileName) { String uuidFilePath = null; int code = makeUuidFileName.hashCode(); //获得到文件的hascode码 8 int dir1 = code & 0xF; //3 int dir2 = code & 0xF; //8 File file = new File(uploadPath+"/"+dir1+"/"+dir2); if(!file.exists()){ //如果说文件路径不存在的话,那么就一次创建多个目录 file.mkdirs(); } uuidFilePath = file.getPath(); return uuidFilePath; } /** *写一个算法,给每一张图片起一个唯一的名字,这样在上传同一张图片的时候就可以有多个 * @param fileName 图片的名字,最后加上文件的名字识别 * @return */ public String makeUuidFileName(String fileName){ return UUID.randomUUID().toString()+"_"+fileName; }</font>
(二) 第一种重构的方式比较简单:也就是把原代码中能够抽取出来的方法,全部抽取出来放在一个UploadUtil类中,然后再原来的方法中调用该静态方法就可以
注意:这里的源码没有列举出来,只是列举方法名而已。具体的实现源码我已经导成了一个jar包。如果有兴趣的可以下载该jar包研究一下啊。或者学习者自己重构
//取得上传的真实路径和临时路径 public static final String tempPath = "/WEB-INF/temp"; public static final String uploadPath ="/WEB-INF/upload"; /* * 对于ie浏览器的话上传路径是C:\Users\admin\Desktop\1.jpg, * 而对于一些高级浏览器火狐之类的路径是1.jpg。 因此要对路径做一个处理。只需要1.jsp就可以 */ public static String getRealFileName(String realFileName){ //代码忽略了 return 1.jpg return realFileName; } /**取得upload目录下面的子目录 * @param uploadPath :upload * @param makeUuidFileName : a.jpg * @return upload/8/8 */ public static String makeUuidFilePath(String uploadPath, String makeUuidFileName) { //代码忽略了 返回 upload/8/8 return uuidFilePath; } /** * 取得文件的uuid名字 *写一个算法,给每一张图片起一个唯一的名字,这样在上传同一张图片的时候就可以有多个 * @param fileName 图片的名字,最后加上文件的名字识别 * @return */ public static String makeUuidFileName(String fileName){ return UUID.randomUUID().toString()+"_"+fileName; } /* *文件保存,也就是Io流那个 */ public static void doSave(InputStream is,String makeUuidFilePath ,String makeUuidFileName){ //代码忽略了 返回 true/false return true/false }
(三)第二种重构就更加的简洁了
只需要调用
UploadUtil.doUpload();
UploadUtil.doSave();
两个方法就可以实现保存。
这种简介的代码才是我们所追求的。
测试案例: public void doPost(HttpServletRequest request, HttpServletResponse response) throws Exception { try { User user = UploadUtil.doUpload(request); String uploadPath = this.getServletContext().getRealPath(UploadUtil.uploadPath); UploadUtil.doSave(user,uploadPath); request.setAttribute("message", "上传成功"); request.getRequestDispatcher("/WEB-INF/message.jsp").forward(request, response); } catch (FileUploadException e) { e.printStackTrace(); request.setAttribute("message", "上传失败"); request.getRequestDispatcher("/WEB-INF/message.jsp").forward(request, response); } }
//第二种封装方式,把上传文件分装成javaBean public static User doUpload(HttpServletRequest request) throws Exception{ //代码忽略了 return user; } //javaBean的保存文件 public static void doSave(User user,String uploadPath) throws IOException{ //代码忽略了 }
- java之文件上传二(源码)
- Java源码文件上传
- java之上传文件的细节(都可以在源码体现,抽取出来讲呗)
- 文件上传二之ajaxupload
- CI框架源码解析二十之文件上传类文件Upload.php
- JAVA之"文件上传"
- java之上传文件
- java之上传文件
- JAVA之文件上传
- 【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【控制文件上传和下载】
- 文件上传(二)
- java框架之struts2(文件上传)
- Spring Framework源码(十):SpringMVC之文件上传
- Volley源码分析之自定义MultiPartRequest(文件上传)
- protoc编译proto文件之Java源码结构分析二(person.proto)
- SpringMVC 源码之文件上传 MultipartResolver
- java FTP上传发布文件源码示例
- webuploader java上传文件后台源码 mpush
- TIFF坐标的转换,生成新的图像
- 数据结构之 栈(C语言实现)
- 端点描述符
- Makefile学习之ESP8266官方工程的Makefile
- 【bzoj3531】[Sdoi2014]旅行
- java之文件上传二(源码)
- MySQL分区表的局限和限制
- 后台截取字符串的长度
- chmod的使用以及文件的命名
- 数据库应用优化(1)
- 《一本书读懂TCP/IP》读后感——第四章TCP/IP网络机构
- python 生成器和lambda的故事
- linux下的压缩与解压命令以及磁盘加载
- 二分法查询(某个网站的面试题)