Java培训之javaweb课程文件上传下载

1.文件上传

1.1提出问题

客户需要将自己的文件上传给服务器怎么处理?

文件上传的时候是怎样提交给服务器的?

 

答:我们可以使用multipart/form-data表单处理文件上传

         文件的上传是以流的形式提交给服务器的

1.2文件上传步骤

文件上传我们需要用到两个包。commons-fileupload-1.3.1.jar、commons-io-2.4.jar。

所以先导入包。然后进行文件上传测试

文件上传步骤:

1)修改表单enctype值为multipart/form-data,并且method=post

<form action=“upload” method=“post” enctype=“multipart/form-data”>

                  <input type=“file” name=“file”>

                  <input type=“submit”>

</form>

2)创建文件上传请求解析器

在doPost方法中创建ServletFileUpload对象,并传入DiskFileItemFactory工厂对象

DiskFileItemFactory factory = new DiskFileItemFactory();

                  ServletFileUpload fileUpload = new ServletFileUpload(factory);

3)解析并上传文件

解析上传文件请求

List<FileItem> list = fileUpload.parseRequest(request);

                          for(FileItem f : list){

                                   if(f.isFormField()){//普通表单项

 

                                   }else{ //文件表单项

                                            String name = f.getName();

                                            System.out.println(name);

                                            f.write(new File(“D:/”+name));

                                   }

}

 

注意事项:

①、当文件上传表单的文件项未选择文件时,文件大小为0,应该做判断,当文件大小为0则不进行上传

②、使用fileItem.getName()获取文件名。在火狐谷歌下,为文件的名字。在ie下为文件的路径,因此要获取文件名需要进行处理

③、使用fileItem.getString(“utf-8”),获取文件普通表单项的值

 

完整的文件上传代码:

protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {

                  // 1、创建fileItem工厂

                  DiskFileItemFactory factory = new DiskFileItemFactory();

                  // 2、创建文件上传对象

                  ServletFileUpload fileUpload = new ServletFileUpload(factory);

                  // 3、解析文件上传请求

                  try {

                          List<FileItem> list = fileUpload.parseRequest(request);

                          // 4、遍历解析出的每个FileItem文件

                          for (FileItem f : list) {

                                   // 这是普通表单项

                                   if (f.isFormField()) {

                                            // 表单项的name值

                                            String fieldName = f.getFieldName();

                                            // 表单项value,使用编码取得中文

                                            String fieldValue = f.getString(“utf-8”);

                                            System.out.println(fieldName + “:” + fieldValue);

 

                                   // 表示文件表单项

                                   } else {

                                            //获取文件大小,有可能并没有上传文件

                                            long size = f.getSize();

                                            if(size == 0){

                                                     continue;

                                            }

 

                                            // 获取文件名字

                                            String name = f.getName();

                                            // ie下是全路径,火狐谷歌为文件名,需要不同处理

                                            if (name.contains(“\\”)) {

                                                     name = name.substring(name.lastIndexOf(“\\”) + 1);

                                            }

 

                                            //获取文件保存的服务端路径

                                            String realPath = request.getServletContext().getRealPath(“/upload”);

                                            File file = new File(realPath);

                                            if(!file.exists()){

                                                     file.mkdirs();

                                            }

                                            //生成一个唯一不重复的文件名

                                            name = UUID.randomUUID().toString().replace(“-“, “”)+”-“+name;

                                            //将文件内容写入

                                            f.write(new File(realPath+”/”+name));

                                   }

                          }

                  } catch (FileUploadException e) {

                          e.printStackTrace();

                  } catch (Exception e) {

                          e.printStackTrace();

                  }

                  response.setContentType(“text/html;charset=UTF-8”);

                  response.getWriter().write(“上传完成!”);

         }

 

其他注意:

fileUpload可以来限制文件的大小

                  //设置当文件的大小为50KB

                  //fileUpload.setFileSizeMax(1024*50);

 

                  //设置多个文件的总大小为150KB

                  fileUpload.setSizeMax(1024*150);

 

当文件超出大小限制的时候会抛出异常,增加catch子句来处理

catch (SizeLimitExceededException e) {

                          response.setContentType(“text/html;charset=UTF-8”);

                          response.getWriter().write(“文件大小超出限制”);

                          return;

                  }

 

原理:

分析文件上传的请求我们会发现,文件上传的时候request的body会增加一个分界符,分界符用来分割正常的表单域和文件表单域,文件的内容在分界符的中间,以流的形式传递,文件上传的request请求如下:

Java培训

以上是请求头;

下面是请求体携带的数据:

java培训

2.文件下载

2.1提出问题

如何把服务器上的文件传输给客户端。href可以吗?href可以传送某些资源,当客户端不支持此资源的显示或者打开时,就会启动下载。但是如果客户端支持显示或者打开此资源。如:图片,视频,音频,文本文件等。浏览器会直接打开他们。我们需要浏览器进行下载操作。所以单纯的href已经不能操作了。

如果资源文件是比较重要的文件,我们需要放到WEB-INF下将其保护,那么href是链接不到的。

2.2文件下载步骤

2.2.1下载步骤:

         1)设置响应体

         response.setContentType(this.getServletContext().getMimeType(“abc.txt”));

         response.setHeader(“Content-Disposition”, “attachment;filename=”+”abc.txt”);

         2)输出文件流

         FileInputStream fis = new          FileInputStream(this.getServletContext().getRealPath(“/abc.txt”));

         ServletOutputStream stream = response.getOutputStream();

         IOUtils.copy(fis, stream); //使用commons.io工具输出流

         fis.close();

2.2.2存在的问题:

         1)文件名为中文

  • 使用encode方法将文件名进行编码

         String fileName = URLEncoder.encode(“中文.txt”,”utf-8″);

         response.setHeader(“Content-Disposition”, “attachment;filename=”+fileName);

                  火狐不支持,显示格式不正确

 

         火狐需要使用base64编码,加上utf-8标注。

                  String fileName = “”;

                  String header = request.getHeader(“User-Agent”);

                  if(header.contains(“Firefox”)){

         fileName = “=?utf-8?b?”+new                                                   BASE64Encoder().encode(name.getBytes(“utf-8″))+”?=”;

                  }else{

                           fileName = URLEncoder.encode(“中文.txt”,”utf-8″);

                  }

  • 先用GBK解码,再使用iso8859-1编码

String fileName = new String(name.getBytes(“gbk”),”iso8859-1″);

         response.setHeader(“Content-Disposition”, “attachment;filename=”+fileName);

 

想要了解跟多关于Java培训课程内容欢迎关注尚硅谷Java培训,尚硅谷除了这些技术文章外还有免费的高质量Java培训课程视频供广大学员下载。


上一篇:
下一篇: