`

jsp servlet文件上传

 
阅读更多
一、文件上传的基本操作:
1、 表单属性enctype的设置

multipart/form-data和application/x-www-form-urlencoded的区别

<!-- 编写文件上传表单
 1、提供文件上传输入项 <input type="file" />
 2、input file 必须提供name 属性(没有name 属性表单项,不会提交)value可以重复但是必须得有
 3、表单method属性 必须post(GET提交方式,提交数据有长度限制,上传文件可能会很大)
 4、form的enctype属性 必须设置 multipart/form-data
 -->
FORM元素的enctype属性指定了表单数据向服务器提交时所采用的编码类型,默认的缺省值是“application/x-www-form-urlencoded”。

然而,在向服务器发送大量的文本、包含非ASCII字符的文本或二进制数据时这种编码方式效率很低。

在文件上传时,所使用的编码类型应当是“multipart/form-data”,它既可以发送文本数据,也支持二进制数据上传。

Browser端<form>表单的ENCTYPE属性值为multipart/form-data,它告诉我们传输的数据要用到多媒体传输协议,由于多媒体传输的都是大量的数据,所以规定上传文件必须是post方法,<input>的type属性必须是file。
要获取提交过来的数据可以用request.getInputstream()再放到输出流输出发现输出的是

-----------------------------7dd32c39803b2
Content-Disposition: form-data; name="username"

wzhting
-----------------------------7dd32c39803b2
Content-Disposition: form-data; name="f1"; filename="C:\Documents and Settings\wzhting\妗岄潰\a.txt"
Content-Type: text/plain

aaaaaaaaaaaaaaaaaa
-----------------------------7dd32c39803b2
Content-Disposition: form-data; name="f2"; filename="C:\Documents and Settings\wzhting\妗岄潰\b.txt"
Content-Type: text/plain

bbbbbbbbbbbbbbbbbbb
-----------------------------7dd32c39803b2--

这样的话得分割比较麻烦所以apache开发了上传工具
实现过程:

导入apache的两个jar:commons-fileupload.jar和commons-io.jar
DiskFileItemFactory:设置环境-》ServletFileUpload:核心上传类(主要作用:解析请求的正文内容)-》FileItem:代表表单中的一个输入域。
DiskFileItemFactory:
public void setSizeThreshold(int?sizeThreshold) :设置缓冲区大小。默认是10Kb。
当上传的文件超出了缓冲区大小,fileupload组件将使用临时文件缓存上传文件
public void setRepository(java.io.File repository):设置临时文件的存放目录。默认是系统的临时文件存放目录。
DiskFileItemFactory(int size,File file);
 
ServletFileUpload:
boolean isMultipartContent(HttpServletRequest?request):判断用户的表单的enctype是否是multipart/form-data类型的。
List parseRequest(HttpServletRequest request):解析请求正文中的内容返回List<FileItem>
setFileSizeMax(4*1024*1024);//设置单个上传文件的大小
upload.setSizeMax(6*1024*1024);//设置总文件大小
 
FileItem
1.获取普通字段信息:
boolean isFormField():是否是普通字段
String getFieldName:获取普通字段的字段名
String getString():获取普通字段的值
2.获取上传文件信息:
InputStream getInputStream():获取上传字段的输入流
String getName():获取上传的文件名
最普通的文件上传:
 public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  response.setContentType("text/html;utf-8");
  response.setCharacterEncoding("utf-8");
  DiskFileItemFactory factory=new DiskFileItemFactory();
  ServletFileUpload load=new ServletFileUpload(factory);
  load.setHeaderEncoding("UTF-8");
  if(!load.isMultipartContent(request)){
   return;
  }
  try {
   List<FileItem> list=load.parseRequest(request);
   for(FileItem item: list){
    if(item.isFormField())
    {
     String name=item.getFieldName();
     String value=item.getString("utf-8");
     response.getWriter().write(name+"="+value);
    }
    else
    {
     String real=getServletContext().getRealPath("/WEB-INF/upload");
     String filename=item.getName();
     filename=filename.substring(filename.lastIndexOf("\\")+1);
     response.getWriter().write("<br />文件名:"+filename);
     FileOutputStream fos=new FileOutputStream(real+"\\"+filename);
     InputStream ins=item.getInputStream();
     byte buf[]=new byte[1024];
     int len=0;
     while((len=ins.read(buf))>0){
      fos.write(buf,0,len);
     }
     ins.close();
     fos.close();
    }
   }
  } catch (FileUploadException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
 public void doPost(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  doGet(request, response);

 }

}

要注意的9个问题
1、如何保证服务器的安全
把保存上传文件的目录放到WEB-INF目录中。
2、中文乱码问题
2.1普通字段的中文请求参数
String value = FileItem.getString("UTF-8");
2.2上传的文件名是中文
解决办法:request.setCharacterEncoding("UTF-8");
3、重名文件被覆盖的问题
System.currentMillions()+"_"+a.txt(乐观)

UUID+"_"+a.txt:保证文件名唯一
4、分目录存储上传的文件
方式一:当前日期建立一个文件夹,当前上传的文件都放到此文件夹中。
方式二:利用文件名的hash码打散目录来存储。
int hashCode = fileName.hashCode();

1001 1010 1101 0010 1101 1100 1101 1010
hashCode&0xf; 0000 0000 0000 0000 0000 0000 0000 1111 &
---------------------------------------------
0000 0000 0000 0000 0000 0000 0000 1010 取hashCode的后4位
0000~1111:整数0~15共16个

1001 1010 1101 0010 1101 1100 1101 1010
(hashCode&0xf0)0000 0000 0000 0000 0000 0000 1111 0000 &
--------------------------------------------
0000 0000 0000 0000 0000 0000 1101 0000 >>4
--------------------------------------------
0000 0000 0000 0000 0000 0000 0000 1101
0000~1111:整数0~15共16个
5、限制用户上传的文件类型
通过判断文件的扩展名来限制是不可取的。
通过判断其Mime类型才靠谱。FileItem.getContentType();
6、如何限制用户上传文件的大小
6.1单个文件大小限制。超出了大小友好提示
抓异常进行提示:org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException
6.2总文件大小限制。超出了大小友好提示
抓异常进行提示:org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException
7、临时文件的问题
commons-fileupload组件不会删除超出缓存的临时文件。

FileItem.delete()方法删除临时文件。但一定要在关闭流之后。
8、多个文件上传时,没有上传内容的问题
if(fileName==null||"".equals(fileName.trim())){
continue;
}
9、上传进度检测
给ServletFileUpload注册一个进度监听器即可,把上传进度传递给页面去显示
//pBytesRead:当前以读取到的字节数
//pContentLength:文件的长度
//pItems:第几项
public void update(long pBytesRead, long pContentLength,
int pItems) {
System.out.println("已读取:"+pBytesRead+",文件大小:"+pContentLength+",第几项:"+pItems);
}

 

完整文件上传代码:

 

public void doPost(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  request.setCharacterEncoding("UTF-8");// 中文文件名乱码问题
  response.setContentType("text/html;charset=UTF-8");
  PrintWriter pout = response.getWriter();
  DiskFileItemFactory df = new DiskFileItemFactory(1024 * 1024, new File(
    "d:" + File.separator + "cache"));
  ServletFileUpload sfu = new ServletFileUpload(df);
  if (!sfu.isMultipartContent(request)) {
   System.out.println("提交类型不对");
  } else {
   try {
    //进度条
/*    sfu.setProgressListener(new ProgressListener() {
     //pBytesRead读取的字节数 pContentLength总长度 pItems读取了第几个
     public void update(long pBytesRead, long pContentLength,
       int pItems) {
      // TODO Auto-generated method stub
      System.out.println("已读取:"+pBytesRead+",文件大小:"+pContentLength+",第几项:"+pItems);
     }
    });*/
    List<FileItem> list = sfu.parseRequest(request);
    // sfu.setFileSizeMax(4 * 1024 * 1024);// 设置单个上传文件的大小
    // sfu.setSizeMax(6 * 1024 * 1024);// 设置总文件大小
    for (FileItem item : list) {
     if (item.isFormField()) {
      System.out.println(item.getFieldName() + ":"
        + item.getString("utf-8"));// form表单参数乱码问题
     } else {
      String mimeType = item.getContentType();
      // if (mimeType.startsWith("image"))
      if (1 == 1) {// 限制上传文件类型只能为图片
       String fileName = item.getName();
       if (fileName == null || "".equals(fileName.trim())) {// 多个文件上传时,没有上传内容的问题
        continue;
       }
       fileName = fileName.substring(fileName
         .lastIndexOf("\\") + 1);
       String storePath = getServletContext().getRealPath(
         "/WEB-INF/Files");
       InputStream is = item.getInputStream();
       fileName = UUID.randomUUID() + "_" + fileName;// 防止文件名重复
       storePath = makeStorePath(storePath, fileName);// 多文件夹存储
       OutputStream fos = new FileOutputStream(storePath
         + File.separator + fileName);
       BufferedOutputStream out = new BufferedOutputStream(
         fos);
       byte b[] = new byte[1024];
       int len = -1;
       while ((len = is.read(b)) != -1) {
        out.write(b, 0, len);
       }
       is.close();
       out.close();
       item.delete();//必须关闭is和out后删除临时文件
      }
     }
    }
   } /*catch (org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException e) {
    // 单个文件超出大小时的异常
    pout.write("单个文件大小不能超出4M");
   } catch (org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException e) {
    // 总文件超出大小时的异常
    pout.write("总文件大小不能超出6M");
   } */catch (FileUploadException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   response.sendRedirect("/ServletFileUpload/ok.jsp");
  }
 }

 private String makeStorePath(String storePath, String fileName) {
  // TODO Auto-generated method stub
  int hashCode = fileName.hashCode();
  int dir1 = hashCode & 0xf;// 0000~1111:整数0~15共16个
  int dir2 = (hashCode & 0xf0) >> 4;// 0000~1111:整数0~15共16个
  String newstore = storePath + File.separator + dir1 + File.separator
    + dir2;
  File file = new File(newstore);
  if (!file.exists()) {
   file.mkdirs();// 递归创建目录
  }
  return newstore;
 }

 

 

 

 

ok
分享到:
评论

相关推荐

    jspservlet文件上传实例

    ### jspservlet文件上传实例详解 #### 一、概述 在现代Web开发中,文件上传是常见需求之一,尤其在用户交互频繁的应用场景下尤为重要。本文将深入解析一个基于JSP与Servlet技术实现的文件上传实例,通过分析其代码...

    JSP中(jsp+servlet)实现的文件上传

    通过以上步骤,你将在Glassfish v2服务器上实现一个基本的JSP+Servlet文件上传功能,只允许上传.gif和.jpg格式的图片,同时阻止.exe和.bat等可能带有恶意代码的文件。这样的功能在实际应用中非常实用,如用户头像...

    文件上传源码(jsp+servlet)

    实现简单的文件上传功能。 在工程中加入io和upload组件的方法: Windows-preferences-Java-buildpath-userlibraries 右击工程名:buildpath-config buildpath-libraries-addlibraries-userliraries-next,加入包即可...

    jsp+servlet文件上传

    `JSP(JavaServer Pages)`和`Servlet`是Java EE平台上的两种核心技术,它们常用于构建动态Web项目,包括文件上传功能。本篇文章将深入讲解如何使用JSP和Servlet实现文件上传。 首先,我们需要了解`JSP`的基本概念...

    jsp+servlet实现文件上传下载

    ### jsp+servlet实现文件上传下载 在现代Web开发中,文件上传下载是常见的功能之一。JSP(JavaServer Pages)与Servlet技术结合可以轻松实现这一功能。本篇将详细介绍如何利用jspSmartUpload组件实现文件的上传与...

    jsp与servlet 上传文件 javaBean上传文件

    在处理文件上传需求时,JSP通常作为前端界面,而Servlet则负责后端逻辑处理。本篇文章将深入探讨如何使用JSP与Servlet进行文件上传,并特别关注如何解决中文文件名乱码的问题。 首先,我们需要理解文件上传的基本...

    JSP+Servlet实现文件上传到服务器功能

    本文实例为大家分享了JSP+Servlet实现文件上传到服务器功能的具体代码,供大家参考,具体内容如下 项目目录结构大致如下: 正如我在上图红线画的三个东西:Dao、service、servlet 这三层是主要的结构,类似 MVC ...

    jsp servlet 上传文件

    本篇将详细讲解如何使用`JSP`和`Servlet`合作实现文件上传功能,特别是针对图片文件的上传。 一、JSP简介 JSP是一种基于Java的服务器端脚本语言,它允许开发者在HTML或XML文档中嵌入Java代码,用于创建动态网页。...

    用JSPServlet实现文件上传.rar

    【摘要】:该文介绍了在B/S模式下,通过JSP/Servlet技术实现文件上传的方法。 文件上传在很多网站应用中是必不可少的,在电子商务中上传商品图片,在音乐网站中上传流行歌曲……一个高效率的文件上传功能尤为重要。...

    jsp+servlet文件上传数据库和下载

    在Java Web开发中,"jsp+servlet文件上传数据库和下载"是常见的功能需求,涉及到的主要技术包括JSP(JavaServer Pages)、Servlet、文件处理以及数据库操作。以下将详细阐述这些知识点。 1. JSP(JavaServer Pages...

    jsp servlet 上传例子 基于 jspsmartupload

    本教程将详细讲解如何使用 `JSP` 和 `Servlet` 结合 `jspsmartupload` 库来实现文件上传功能。 首先,我们需要了解`jspsmartupload`库。`jspsmartupload` 是一个基于Java的开源项目,专门设计用于在`JSP`页面上处理...

    jsp,servlet上传下载文件

    jsp、servlet 文件上传下载技术详解 文件上传下载是 Web 应用中的一种常见需求,使用 jsp 页面和 servlet 实现文件上传下载是其中的一种解决方案。下面将详细介绍 jsp、servlet 文件上传下载技术。 文件上传下载...

    JSP+servlet文件上传简单案例

    在这个“JSP+servlet文件上传简单案例”中,我们将探讨如何利用这两种技术实现文件上传功能。文件上传是Web应用中常见的一种需求,例如用户可能需要上传个人头像、文档或者其他形式的数据。 首先,让我们了解一下...

    基于jsp的文件上传下载

    总之,基于JSP的文件上传下载是Java Web开发中的基础技能,它结合了HTML、JavaScript、Servlet和JavaBean等技术,通过合理的服务器端处理和客户端交互,实现了用户友好的文件操作功能。理解并掌握这部分知识,对于...

    jsp+servlet文件上传,非apache组件

    本教程将探讨如何使用纯JSP(JavaServer Pages)和Servlet技术来实现文件上传,而不依赖Apache的文件上传组件,如Commons FileUpload。 首先,我们需要了解JSP和Servlet的基本概念。JSP是用于创建动态网页的Java...

    JSP+Servlet文件上传下载实例

    在Java Web开发中,JSP(Java...总的来说,JSP+Servlet实现文件上传下载涉及到HTML表单、Servlet请求处理、文件I/O以及第三方库的使用。通过这个实例,开发者可以掌握在Java Web环境中处理文件上传下载的基本流程。

    servlet jsp javabean 实现的文件上传

    综上所述,Servlet、JSP和JavaBean协同工作,实现了用户友好的文件上传功能。Servlet处理HTTP请求,JSP提供用户界面,JavaBean封装业务逻辑,共同构建了一个安全、可控的文件上传系统。通过合理的代码组织和优化,...

    jsp+servlet头像上传功能

    总结来说,`jsp+servlet头像上传功能`涉及到的主要知识点包括:`JSP`用于创建用户界面,`Servlet`处理文件上传逻辑,以及可能的文件验证、存储、预览和数据库操作。理解并熟练掌握这些技术,是构建高效、安全的Web...

    JSP+servlet文件上传

    在Java Web开发中,JSP(JavaServer Pages)和Servlet是两种常见的技术,它们可以协同工作来处理用户请求,包括文件上传功能。本教程将详细讲解如何使用JSP和Servlet实现文件上传,以及相关的知识点。 一、JSP与...

Global site tag (gtag.js) - Google Analytics