1.1 文件上传三要素

提供form表单,method必须是post

form表单的enctype必须是multipart/form-data

提供 input type=“file” 类型输入

1.2 实现文件上传

1.2.1 项目准备

​ 导入: commons-fileupload.jar

​ commons-io.jar

1.2.2 编写上传页面

<%@ page language="java" pageEncoding="UTF-8"%>

<!DOCTYPE HTML>

<html>

<head>

<title>文件上传</title>

</head>

<body>

<form action="${pageContext.request.contextPath}/servlet/UploadHandleServlet" enctype="multipart/form-data" method="post">

上传用户:<input type="text" name="username"><br/>

上传文件1:<input type="file" name="file1"><br/>

上传文件2:<input type="file" name="file2"><br/>

<input type="submit" value="提交">

</form>

</body>

</html>

1.2.3 编写处理代码

package me.gacl.web.controller;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.util.List;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;

import org.apache.commons.fileupload.disk.DiskFileItemFactory;

import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class UploadHandleServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

//得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全

String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");

File file = new File(savePath);

//判断上传文件的保存目录是否存在

if (!file.exists() && !file.isDirectory()) {

System.out.println(savePath+"目录不存在,需要创建");

//创建目录

file.mkdir();

}

//消息提示

String message = "";

try{

//使用Apache文件上传组件处理文件上传步骤:

//1、创建一个DiskFileItemFactory工厂

DiskFileItemFactory factory = new DiskFileItemFactory();

//2、创建一个文件上传解析器

ServletFileUpload upload = new ServletFileUpload(factory);

//解决上传文件名的中文乱码

upload.setHeaderEncoding("UTF-8");

//3、判断提交上来的数据是否是上传表单的数据

if(!ServletFileUpload.isMultipartContent(request)){

//按照传统方式获取数据

return;

}

//4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项

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

for(FileItem item : list){

//如果fileitem中封装的是普通输入项的数据

if(item.isFormField()){

String name = item.getFieldName();

//解决普通输入项的数据的中文乱码问题

String value = item.getString("UTF-8");

//value = new String(value.getBytes("iso8859-1"),"UTF-8");

System.out.println(name + "=" + value);

}else{//如果fileitem中封装的是上传文件

//得到上传的文件名称,

String filename = item.getName();

System.out.println(filename);

if(filename==null || filename.trim().equals("")){

continue;

}

//注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如:  c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt

//处理获取到的上传文件的文件名的路径部分,只保留文件名部分

filename = filename.substring(filename.lastIndexOf("\\")+1);

//获取item中的上传文件的输入流

InputStream in = item.getInputStream();

//创建一个文件输出流

FileOutputStream out = new FileOutputStream(savePath + "\\" + filename);

//创建一个缓冲区

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();

message = "文件上传成功!";

}

}

}catch (Exception e) {

message= "文件上传失败!";

e.printStackTrace();

}

request.setAttribute("message",message);

request.getRequestDispatcher("/message.jsp").forward(request, response);

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doGet(request, response);

}

}

1.2.4 配置

<servlet>

<servlet-name>UploadHandleServlet</servlet-name>

<servlet-class>com.qf.web.UploadHandleServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>UploadHandleServlet</servlet-name>

<url-pattern>/servlet/UploadHandleServlet</url-pattern>

</servlet-mapping>

1.3 文件上传细节注意

上述的代码虽然可以成功将文件上传到服务器上面的指定目录当中,但是文件上传功能有许多需要注意的小细节问题,以下列出的几点需要特别注意的

1、为保证服务器安全,上传文件应该放在外界无法直接访问的目录下,比如放于WEB-INF目录下。

2、为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名。

3、为防止一个目录下面出现太多文件,要使用hash算法打散存储。

4、要限制上传文件的最大值。

5、要限制上传文件的类型,在收到上传文件名时,判断后缀名是否合法。

最终处理代码改进为:

public class UploadHandleServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

//得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全

String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");

//上传时生成的临时文件保存目录

String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp");

File tmpFile = new File(tempPath);

if (!tmpFile.exists()) {

//创建临时目录

tmpFile.mkdir();

}

//消息提示

String message = “”;

try{

//使用Apache文件上传组件处理文件上传步骤:

//1、创建一个DiskFileItemFactory工厂

DiskFileItemFactory factory = new DiskFileItemFactory();

//设置工厂的缓冲区的大小,当上传的文件大小超过缓冲区的大小时,就会生成一个临时文件存放到指定的临时目录当中。

factory.setSizeThreshold(1024100);//设置缓冲区的大小为100KB,如果不指定,那么缓冲区的大小默认是10KB

//设置上传时生成的临时文件的保存目录

factory.setRepository(tmpFile);

//2、创建一个文件上传解析器

ServletFileUpload upload = new ServletFileUpload(factory);

//解决上传文件名的中文乱码

upload.setHeaderEncoding(“UTF-8”);

//3、判断提交上来的数据是否是上传表单的数据

if(!ServletFileUpload.isMultipartContent(request)){

//按照传统方式获取数据

return;

}

//设置上传单个文件的大小的最大值,目前是设置为10241024字节,也就是1MB

upload.setFileSizeMax(10241024);

//设置上传文件总量的最大值,最大值=同时上传的多个文件的大小的最大值的和,目前设置为10MB

upload.setSizeMax(10241024*10);

//4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List集合,每一个FileItem对应一个Form表单的输入项

List list = upload.parseRequest(request);

for(FileItem item : list){

//如果fileitem中封装的是普通输入项的数据

if(item.isFormField()){

String name = item.getFieldName();

//解决普通输入项的数据的中文乱码问题

String value = item.getString(“UTF-8”);

//value = new String(value.getBytes(“iso8859-1”),“UTF-8”);

System.out.println(name + “=” + value);

}else{//如果fileitem中封装的是上传文件

//得到上传的文件名称,

String filename = item.getName();

System.out.println(filename);

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);

//如果需要限制上传的文件类型,那么可以通过MT4下载教程文件的扩展名来判断上传的文件类型是否合法

System.out.println(“上传的文件的扩展名是:”+fileExtName);

//获取item中的上传文件的输入流

InputStream in = item.getInputStream();

//得到文件保存的名称

String saveFilename = FileUploadUtils.makeFileName(filename);

//得到文件的保存目录

String realSavePath = FileUploadUtils.makePath(saveFilename, savePath);

//创建一个文件输出流

FileOutputStream out = new FileOutputStream(realSavePath + “\” + 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();

message = “文件上传成功!”;

}

}

}catch (FileUploadBase.FileSizeLimitExceededException e) {

e.printStackTrace();

request.setAttribute(“message”, “单个文件超出最大值!!!”);

request.getRequestDispatcher("/message.jsp").forward(request, response);

return;

}catch (FileUploadBase.SizeLimitExceededException e) {

e.printStackTrace();

request.setAttribute(“message”, “上传文件的总的大小超出限制的最大值!!!”);

request.getRequestDispatcher("/message.jsp").forward(request, response);

return;

}catch (Exception e) {

message= “文件上传失败!”;

e.printStackTrace();

}

request.setAttribute(“message”,message);

request.getRequestDispatcher("/message.jsp").forward(request, response);

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doGet(request, response);

}

}

//文件上传工具类

public class FileUploadUtils {

/**

* @Method: makeFileName

* @Description: 生成上传文件的文件名,文件名以:uuid+""+文件的原始名称

* @Anthor:孤傲苍狼

* @param filename 文件的原始名称

* @return uuid+""+文件的原始名称

*/

private static String makeFileName(String filename){ //2.jpg

//为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名

return UUID.randomUUID().toString() + “_” + filename;

}

/**

* 为防止一个目录下面出现太多文件,要使用hash算法打散存储

* @param filename 文件名,要根据文件名生成存储目录

* @param savePath 文件存储路径

* @return 新的存储目录

*/

private static  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

//File既可以代表文件也可以代表目录

File file = new File(dir);

//如果目录不存在

if(!file.exists()){

//创建目录

file.mkdirs();

}

return dir;

}

}

1.4 Servlet3.1支持的文件上传

package com.qf.servlet;

import java.io.IOException;

import java.util.Collection;

import javax.servlet.ServletException;

import javax.servlet.annotation.MultipartConfig;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.Part;

import org.apache.commons.io.IOUtils;

import com.qf.utils.FileUploadUtils;

/**

* Servlet implementation class UploadFileServlet2

*/

@WebServlet("/upLoadfile2")

@MultipartConfig(fileSizeThreshold=1024*100,maxFileSize=1024*1024*2,maxRequestSize=1024*1024*20)

public class UploadFileServlet2 extends HttpServlet {

private static final long serialVersionUID = 1L;

/**

* @see HttpServlet#HttpServlet()

*/

public UploadFileServlet2() {

super();

// TODO Auto-generated constructor stub

}

/**

* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)

*/

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

//1乱码

request.setCharacterEncoding("utf-8");

response.setContentType("text/html;charset=utf-8");

String savepath=request.getServletContext().getRealPath("/WEB-INF/upload");

File dir=new File(savepath);

if(!dir.exists()){

dir.mkdirs();

}

//2获取多分部集合

Collection<Part> parts = request.getParts();

if(parts!=null){

System.out.println("parts的个数:"+parts.size());

for (Part part : parts) {

System.out.println(part.getClass().getName());

//判断是文件还是普通项

String filename=part.getSubmittedFileName();

System.out.println(filename+"-------------");

if(filename!=null){

//文件

if(filename.trim().length()==0){

continue;

}

//获取真实的文件名:解决IE文件名的问题,兼容chrome

String dis= part.getHeader("Content-Disposition");

String realfilename=dis.substring(dis.lastIndexOf("filename=")+10,dis.length()-1);

realfilename=realfilename.substring(realfilename.lastIndexOf("\\")+1);

List<String> list= Arrays.asList(".jpg",".png",".bmp");

String ext=realfilename.substring(realfilename.lastIndexOf("."));

if(!list.contains(ext)){

response.getWriter().write("您上传的文件类型不支持");

continue;

}

//生成带uuid文件名

String uuidfilename=UpLoadUtils.createNewFileName(realfilename);

//分散存储

String newpath=UpLoadUtils.createNewPath(savepath, realfilename);

//保存文件

part.write(newpath+"/"+uuidfilename);

response.getWriter().write("上传成功:"+realfilename);

part.delete();//删除缓存文件

}else{

//普通项

String name=part.getName();

String value = request.getParameter(name);

System.out.println(name+"..."+value);

}

}

}

}

/**

* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)

*/

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

// TODO Auto-generated method stub

doGet(request, response);

}

}

javaWEB 之文件的上传的更多相关文章

  1. JavaWeb中文件的上传和下载

    JavaWeb中文件的上传和下载 转自: JavaWeb学习总结(五十)——文件上传和下载 - 孤傲苍狼 - 博客园https://www.cnblogs.com/xdp-gacl/p/4200090 ...

  2. Javaweb之文件的上传与下载

    Javaweb之文件的上传与下载 一.基于表单的文件上传 如果在表单中使用表单元素 <input type=“file” />,浏览器在解析表单时,会自动生成一个输入框和一个按钮,输入框可 ...

  3. JavaWeb 之文件的上传下载

    又到了每周更新博客的时候了,每看到自己发布的随笔阅读量上涨的时候就特别开心,我也会尽自己的努力提高自己的水平,总结出通俗易读的学习笔记,还望大家能多多支持!!! ------------------- ...

  4. JAVAWEB之文件的上传下载

    文件上传下载 文件上传: 本篇文章使用的文件上传的例子使用的都是原生技术,servelt+jdbc+fileupload插件,这也是笔者的习惯,当接触到某些从未接触过的东西时,总是喜欢用最原始的东西将 ...

  5. JAVAWEB之文件的上传和下载

    一.文件的上传: Enctype的属性介绍: 基于表单文件上传的界面简介: 文件上传时服务器端获取不到请求信息的原因及获取请求信息的几种方式: 输入流方式的实现: 实用工具包的实现:要导入fileup ...

  6. 小白养成记——JavaWeb之文件的上传

    文件的上传推荐使用commons的fileupload组件来完成.该组件还依赖于io包,因此需要用到两个jar包: commons-fileupload-X.X.jar commons-io-X.X. ...

  7. 【JAVAWEB学习笔记】29_文件的上传------commons-fileupload

    今天内容: 文件的上传------commons-fileupload 文件上传和下载的实质:文件的拷贝 文件上传:从本地拷贝到服务器磁盘上   客户端需要编写文件上传表单---->服务端需要编 ...

  8. JavaWeb框架_Struts2_(七)----->文件的上传和下载

    这个章节是Struts2框架应用最广泛的三个版块(上传下载.国际化.校验输入)之一,所以这一版块的学习还蛮重要的. 1. 章节目录 Struts2文件上传 单文件上传 拦截器实现文件过滤 文件上传常量 ...

  9. 文件夹上传插件webupload插件

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 先说下要求: PC端全平台支持,要求支持Windows,Mac,Linux 支持所 ...

随机推荐

  1. git注意事项

    1,在github中新建空的工程,第一次提交代码的时候 使用命令  $ git push -u origin master -f 后面就直接push就行了

  2. OpenCV常用基本处理函数(8)图像变换

    傅里叶变换 傅里叶变换在实际中有非常明显的物理意义,设f是一个能量有限的模拟信号,则其傅里叶变换就表示f的频谱. 图像的频率是表征图像中灰度变化剧烈程度的指标,是灰度在平面空间上的梯度.如:大面积的沙 ...

  3. Hadoop(一)阿里云hadoop集群配置

    集群配置 三台ECS云服务器 配置步骤 1.准备工作 1.1 创建/bigdata目录 mkdir /bigdatacd /bigdatamkdir /app 1.2修改主机名为node01.node ...

  4. 【集群】Redis集群设计原理

    Redis集群设计包括2部分:哈希Slot和节点主从 节点主从: 主从设计不算什么新鲜玩意,在数据库中我们也经常用主从来做读写分离,直接上图: 图上能看得到的信息: 1, 只有1个Master,可以有 ...

  5. vue基础九

    1.使用组件 1.1注册 要注册一个全局组件,你可以使用 Vue.component(tagName, options). 例如: Vue.component('my-component', { // ...

  6. 【Flutter学习】基本组件之基本滑动PageView组件

    一,概述 PageView 是一个滑动视图列表,它也是继承至 CustomScrollView 的. 二,构造函数 类命构造函数(PageView) PageView 使用场景:创建一个可滚动列表 构 ...

  7. CF 1150 D Three Religions——序列自动机优化DP

    题目:http://codeforces.com/contest/1150/problem/D 老是想着枚举当前在给定字符串的哪个位置,以此来转移. 所以想对三个串分别建 trie 树,然后求出三个t ...

  8. 前端每日实战:80# 视频演示如何用纯 CSS 创作一个自行车车轮

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/XBXEPK 可交互视频 此视频是可 ...

  9. windows下tomcat7+nginx1.8负载均衡

    1.负载平衡是一种常用的跨多个应用程序实例 技术优化资源利用率,最大化吞吐量, 减少延迟,并确保容错配置. 2.使用nginx作为非常有效的HTTP负载均衡器 将流量分发给几个应用程序服务器和改善 性 ...

  10. tp5 thinkphp 使用phpqrcode生成带Logo的二维码

    1 下载生成二维码类库 composer require aferrandini/phpqrcode 2 点击按钮下载 //二维码下载 public function down_qrcode() { ...