1 文件上传表单

1)上传文件的本质是文本复制的过程

2)技术层面,在Java中一定会用到IO操作,主要以二进制方式读写

3)传统方式下,对于上传文件字段不同的浏览器有着不同的解析方式,例如:

IE6:upfile=c:\aa\bb\a.JPG

非IE6: upfile=a.JPG

4)可以将form以MIME协议的方式将上传文件传递到服务端,服务端以二进制流的方式读写

代码:客户端form enctype="multipart/form-data"/>

服务端request.getInputStream()

Tip:文件上传概述

实现web开发中的文件上传功能,需完成如下二步操作:

·在web页面中添加上传输入项

·在servlet中读取上传文件的数据,并保存到本地硬盘中。

如何在web页面中添加上传输入项?

·标签用于在web页面中添加文件上传输入项,设置文件上传输入项时须注意:

·1、必须要设置input输入项的name属性,否则浏览器将不会发送上传文件的数据。

·2、必须把form的enctype属值设为multipart/form-data.设置该值后,浏览器在上传文件时,将把文件数据附带在http请求消息体中,并使用MIME协议对上传的文件进行描述,以方便接收方对上传数据进行解析和处理。

如何在Servlet中读取文件上传数据,并保存到本地硬盘中?

·request对象提供了一个getInputStream方法,通过这个方法可以读取到客户端提交过来的数据。但由于用户可能会同时上传多个文件,在servlet端编程直接读取上传数据,并分别解析出相应的文件数据是一项非常麻烦的工作,示例。

·为方便用户处理文件上传数据,Apache 开源组织提供了一个用来处理表单文件上传的一个开源组件( Commons-fileupload ),该组件性能优异,并且其API使用极其简单,可以让开发人员轻松实现web文件上传功能,因此在web开发中实现文件上传功能,通常使用commons-fileupload组件实现。

使用commons-fileupload组件实现文件上传,需要导入该组件相应的支撑jar包: commons-fileupload和commons-io。commons-io

不属于文件上传组件的开发jar文件,但commons-fileupload 组件从1.1 版本开始,它工作时需要commons-io包的支持。

Tip:fileupload组件工作流程

Tip:核心API—DiskFileItemFactory

DiskFileItemFactory 是创建 FileItem 对象的工厂,这个工厂类常用方法:

·public void setSizeThreshold(int sizeThreshold)

·设置内存缓冲区的大小,默认值为10K。当上传文件大于缓冲区大小时, fileupload组件将使用临时文件缓存上传文件。

·public void setRepository(java.io.File repository)

·指定临时文件目录,默认值为System.getProperty("java.io.tmpdir").

·public DiskFileItemFactory(int sizeThreshold, java.io.File repository)

·构造函数

Tip:核心API—ServletFileUpload

ServletFileUpload 负责处理上传的文件数据,并将表单中每个输入项封装成一个 FileItem 对象中。常用方法有:

·boolean isMultipartContent(HttpServletRequest request)

·判断上传表单是否为multipart/form-data类型

·List parseRequest(HttpServletRequest request)

·解析request对象,并把表单中的每一个输入项包装成一个fileItem 对象,并返回一个保存了所有FileItem的list集合。

·setFileSizeMax(long fileSizeMax)

·设置上传文件的最大值(单位字节)

·setSizeMax(long sizeMax)

·设置上传文件总量的最大值

·setHeaderEncoding(java.lang.String encoding)

·设置编码格式,解决上传中文名文件的问题

Tip:文件上传案例

实现步骤

1、创建DiskFileItemFactory对象,设置缓冲区大小和临时文件目录

2、使用DiskFileItemFactory 对象创建ServletFileUpload对象,并设置上传文件的大小限制。

3、调用ServletFileUpload.parseRequest方法解析request对象,得到一个保存了所有上传内容FileItem的List对象。

4、对list进行迭代,每迭代一个FileItem对象,调用其isFormField方法判断是否是上传文件

·为普通表单字段,则调用getFieldName、getString方法得到字段名和字段值

·为上传文件,则调用getName 、 getInputStream方法得到数据输入流,从而读取上传数据。

Tip:上传文件的处理细节

中文文件名乱码问题

·文件名中文乱码问题,可调用ServletFileUpload的setHeaderEncoding方法,或者设置request的setCharacterEncoding属性

临时文件的删除问题

·由于文件大小超出DiskFileItemFactory.setSizeThreshold方法设置的内存缓冲区的大小时,commons-fileupload组件将使用临时文件保存上传数据,因此在程序结束时,务必调用FileItem.delete方法删除临时文件。

delete方法的调用必须位于流关闭之后,否则会出现文件占用,而导致删除失败的情况。

文件存放名字

·为防止多用户上传相同文件名的文件,而导致文件覆盖的情况发生,文件上传程序应保证上传文件具有唯一文件名。

文件存放位置

·为保证服务器安全,上传文件应保存在应用程序的WEB-INF目录下,或者不受WEB服务器管理的目录。

·为防止单个目录下文件过多,影响文件读写速度,处理上传文件的程序应根据可能的文件上传总量,选择合适的目录结构生成算法,将上传文件分散存储到不同的目录。

//全局变量

var time = 0;

function addLine(addButton){

//创建内部div对象

var divElement = document.createElement("div");

//创建input对象[file类型]

var inputElement1 = document.createElement("input");

inputElement1.type="file";

inputElement1.name="upfile";

//创建input对象[button类型]

var inputElement2 = document.createElement("input");

inputElement2.type="button";

inputElement2.value="删除";

//对删除按钮添加事件监听

inputElement2.οnclick=function(){

//取得该按钮所在行的直接父元素

var divElement = this.parentNode.parentNode;

//通过父元素删除直接子元素

divElement.removeChild(this.parentNode);

time--;

if(time < 5){

//按钮生效

addButton.disabled=false;

//addButton.style.visibility="visible";

}

}

//依次将file类型和button类型的input对象加入到内部div对象中

divElement.appendChild(inputElement1);

divElement.appendChild(inputElement2);

//再次内部div对象加入到外部div对象

var outDivElement = document.getElementById("outDiv");

outDivElement.appendChild(divElement);

time++;

if(time == 5){

//将按钮失效

addButton.disabled=true;

//addButton.style.visibility="hidden";

}

}

文件上传上传用户

--%>

/>

显示下载文件

package cn.itcast.web.servlet.upload;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.util.List;

import java.util.UUID;

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

//创建上传文件工厂

DiskFileItemFactory factory = new DiskFileItemFactory();

//设置内存中缓存区的大小,默认10K

factory.setSizeThreshold(100*1024);

//设置上传文件临时存放的目录

factory.setRepository(new File(tempPath));

//创建上传文件对象[核心]

ServletFileUpload upload = new ServletFileUpload(factory);

//设置上传文件的中文编码方式

upload.setHeaderEncoding("UTF-8");

//客户端上传文件是否使用MIME协议,

boolean flag = upload.isMultipartContent(request);

if(!flag){

//不是以MIME协议上传文件

throw new ServletException();

}else{

/*是以MIME协议上传的文件,解析request中的所有上传内容

*每个内容封装成一个对象FileItem,

*FileItem代表普通字段和上传字段二类*/

try {

List fileItemList = upload.parseRequest(request);

for(FileItem fileItem : fileItemList){

if(fileItem.isFormField()){

//必定是普通字段

String fieldName = fileItem.getFieldName();

String fieldValue = fileItem.getString("UTF-8");

System.out.println(fieldName+":"+fieldValue);

}else {

//必定是上传字段

String realFileName = fileItem.getName();

int index = realFileName.lastIndexOf("\\");

if(index>=0){

//IE6浏览器

realFileName = realFileName.substring(index+1);

}

//通过真实文件名换算出唯一个文件名

String uuidFileName = makeUuidFileName(realFileName);

//通过位运算换算出upload目录下的子目录

String uuidFilePath = makeUuidFilePath(uploadPath,uuidFileName);

//取得文件输入流

InputStream is = fileItem.getInputStream();

//取得文件输出流

OutputStream os = new FileOutputStream(uuidFilePath+"/"+uuidFileName);

byte[] buf = new byte[1024];

int len = 0;

while( (len=is.read(buf))>0 ){

os.write(buf,0,len);

}

is.close();

os.close();

//将上传文件产生的临时文件删除

fileItem.delete();

request.setAttribute("message","上传文件成功");

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

}

}

} catch (Exception e) {

e.printStackTrace();

request.setAttribute("message","上传文件失败");

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

}

}

/*方式二

InputStream is = request.getInputStream();

OutputStream os = response.getOutputStream();

byte[] buf = new byte[1024];

int len = 0;

while( (len=is.read(buf))>0 ){

os.write(buf,0,len);

}

is.close();

os.close();*/

/*方式一

String username = request.getParameter("username");

String upfile = request.getParameter("upfile");

System.out.println("上传用户:" + username);

System.out.println("上传文件:" + upfile);*/

}

/** uploadPath="/upload"

* uuidFileName="fdafdsfdsa_a.JPG"

* return /upload/8/a 比较难,没看懂*/

private

String makeUuidFilePath(String uploadPath, String uuidFileName) { String uuidFilePath

= null

;

int

code = uuidFileName.hashCode(); //

8

int

dir1 = code & 0xF; //

3

int

dir2 = code >> 4 & 0xF; //

A

File file = new

File(uploadPath+"/"+dir1+"/"+

dir2);

//

如果该目录未存在

if

(!

file.exists()){

//

一次性创建N层目录

file.mkdirs(); } uuidFilePath

=

file.getPath();

return

uuidFilePath;

}

/** realFileName="a.JPG"

* return "fdafdsfdsa_a.JPG"*/

private String makeUuidFileName(String realFileName) {

return UUID.randomUUID().toString()+"_"+realFileName;

}

}

*2 上传文件的细节

(1)中文乱码的问题

a)普通字段的中文乱码问题:FileItem.getString("UTF-8"),

注意:FileItem表示上传表单中的表单项内容

b)上传字段的中文乱码问题:ServletUploadFile.setHeaderEncoding("UTF-8");

(2)临时文件的删除的问题

a)通过FileItem.delete()

b)一定要在关闭IO流之后

(3)在同一个目录下上传相同文件名的问题

a)将文件名拼接一个唯一标识符,即UUID

(4)单个目录下文件过多的问题

a)采用位运算解决单个目录文件过多

b)思路:参见<<>>

(5)为安全将上传的文件放入客户端无法直接访问的目录中的问题

a)将上传的文件,放置到/WEB-INF/upload/目录下

(6)重构思想

a)做到通用性

package cn.itcast.web.servlet.util;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.util.List;

import java.util.UUID;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;

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

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

import cn.itcast.web.servlet.domain.Up;

import cn.itcast.web.servlet.domain.User;

import cn.itcast.web.servlet.exception.NoUpfileException;

import cn.itcast.web.servlet.exception.UpfileSizeException;

public final class UploadUtil {

//取得上传使用的临时和真实目录

public static final String tempPath = "/WEB-INF/temp";

public static final String uploadPath = "/WEB-INF/upload";

//取得真实文件名

public static String getRealFileName(String realFileName){

int index = realFileName.lastIndexOf("\\");

if(index>=0){

//IE6浏览器

realFileName = realFileName.substring(index+1);

}

return realFileName;

}

//取得uuid文件名

public static String makeUuidFilePath(String uploadPath, String uuidFileName) {

String uuidFilePath = null;

int code = uuidFileName.hashCode();//8

int dir1 = code & 0xF;//3

int dir2 = code >> 4 & 0xF;//A

File file = new File(uploadPath+"/"+dir1+"/"+dir2);

//如果该目录未存在

if(!file.exists()){

//一次性创建N层目录

file.mkdirs();

}

uuidFilePath = file.getPath();

return uuidFilePath;

}

//取得upload/目录下的分散目录

public static String makeUuidFileName(String realFileName) {

return UUID.randomUUID().toString()+"_"+realFileName;

}

//文件复制

public static void doSave(InputStream is,String uuidFileName,String uuidFilePath){

OutputStream os = null;

try {

os = new FileOutputStream(uuidFilePath+"/"+uuidFileName);

byte[] buf = new byte[1024];

int len = 0;

while( (len=is.read(buf))>0 ){

os.write(buf,0,len);

}

} catch (Exception e) {

e.printStackTrace();

}finally{

if(is!=null){

try {

is.close();

} catch (IOException e) {

e.printStackTrace();

}

}

if(os!=null){

try {

os.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

//将上传文件封装成JavaBean对象中

public static User doUpload(HttpServletRequest request) throws Exception{

User user = new User();

//创建上传文件工厂

DiskFileItemFactory factory = new DiskFileItemFactory();

//设置内存中缓存区的大小,默认10K

factory.setSizeThreshold(100*1024);

//设置上传文件临时存放的目录

String tempPath = request.getSession().getServletContext().getRealPath(UploadUtil.tempPath);

factory.setRepository(new File(tempPath));

//创建上传文件对象[核心]

ServletFileUpload upload = new ServletFileUpload(factory);

//设置上传文件的中文编码方式

upload.setHeaderEncoding("UTF-8");

//客户端上传文件是否使用MIME协议,

boolean flag = upload.isMultipartContent(request);

if(!flag){

//不是以MIME协议上传文件

throw new ServletException();

}else{

/*是以MIME协议上传的文件,解析request中的所有上传内容

*每个内容封装成一个对象FileItem,

*FileItem代表普通字段和上传字段二类*/

List fileItemList = upload.parseRequest(request);

for(FileItem fileItem : fileItemList){

if(fileItem.isFormField()){

//必定是普通字段

String fieldName = fileItem.getFieldName();

String fieldValue = fileItem.getString("UTF-8");

user.setUsername(fieldValue);

}else {

//必定是上传字段//如果无上传文件

if(fileItem.getSize()==0){

throw new NoUpfileException();

}

String realFileName = UploadUtil.getRealFileName(fileItem.getName());

/*只能上传JPG文件

if(!realFileName.endsWith("JPG")){

throw new UpfileTypeException();

}*/

//只有上传<=200K的文件

if(fileItem.getSize() > 200 * 1024){

throw new UpfileSizeException();

}

//封装到JavaBean

user.getUpfileList().add(fileItem);

}

}//end of for loop

}

return user;

}

public static void doSave(User user, String uploadPath,List upList) throws Exception {

//取得该用户上传的所有文件集合

List fileItemList = user.getUpfileList();

//迭代每个文件,并上传

for(FileItem fileItem : fileItemList){

//创建Up对象

Up up = new Up();

up.setUsername(user.getUsername());

//取得输入流

InputStream is = fileItem.getInputStream();

//取得真实文件名

String realFileName = fileItem.getName();

realFileName = UploadUtil.getRealFileName(realFileName);

//取得UUID文件名

String uuidFileName = UploadUtil.makeUuidFileName(realFileName);

//取得UUID文件路径

String uuidFilePath = UploadUtil.makeUuidFilePath(uploadPath,uuidFileName);

//保存

UploadUtil.doSave(is,uuidFileName,uuidFilePath);

//收集Up信息

up.setUuidFileName(uuidFileName);

up.setRealFileName(realFileName);

upList.add(up);

//删除临时文件

fileItem.delete();

}

}

}

package cn.itcast.web.servlet.upload;

import java.io.IOException;

import java.util.ArrayList;

import java.util.List;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import cn.itcast.web.servlet.domain.Up;

import cn.itcast.web.servlet.domain.User;

import cn.itcast.web.servlet.exception.NoUpfileException;

import cn.itcast.web.servlet.exception.UpfileSizeException;

import cn.itcast.web.servlet.exception.UpfileTypeException;

import cn.itcast.web.servlet.service.UpService;

import cn.itcast.web.servlet.util.UploadUtil;

public class UploadServlet extends HttpServlet {

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

try {

User user = UploadUtil.doUpload(request);

String uploadPath = this.getServletContext().getRealPath(UploadUtil.uploadPath);

List upList = new ArrayList();

//写入硬盘

UploadUtil.doSave(user,uploadPath,upList);

//写入数据库表

UpService upService = new UpService();

upService.addUps(upList);

request.setAttribute("message","上传文件成功");

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

}catch(UpfileSizeException e){

e.printStackTrace();

request.setAttribute("message","上传文件大小限制在200K以内");

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

}catch(UpfileTypeException e){

e.printStackTrace();

request.setAttribute("message","只能上传JPG格式的文件");

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

}catch(NoUpfileException e){

e.printStackTrace();

request.setAttribute("message","无上传文件");

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

}catch (Exception e) {

e.printStackTrace();

request.setAttribute("message","上传文件失败");

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

}

}

}

package cn.itcast.web.servlet.domain;

import java.util.ArrayList;

import java.util.List;

import org.apache.commons.fileupload.FileItem;

//封装上传文件的内容

public class User {

//上传用户

private String username;

//上传的文件

private List upfileList = new ArrayList();

public User(){}

public String getUsername() {

return username;

}

public void setUsername(String username) {

this.username = username;

}

public List getUpfileList() {

return upfileList;

}

public void setUpfileList(List upfileList) {

this.upfileList = upfileList;

}

}

package cn.itcast.web.servlet.domain;

public class Up {

private int id;

private String username;

private String realFileName;

private String uuidFileName;

public Up(){}

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getUsername() {

return username;

}

public void setUsername(String username) {

this.username = username;

}

public String getRealFileName() {

return realFileName;

}

public void setRealFileName(String realFileName) {

this.realFileName = realFileName;

}

public String getUuidFileName() {

return uuidFileName;

}

public void setUuidFileName(String uuidFileName) {

this.uuidFileName = uuidFileName;

}

}

(7)自定义封装上传文件工具类的问题

课堂练习:无上传文件提交/只能上传JPG或jpg文件

(8)上传文件的大小的问题

(9)上传多个文件的问题

(10)上传多个文件的界面问题

Tip:多个文件上传的javascript编码

技巧:

·每次动态增加一个文件上传输入框,都把它和删除按纽放置在一个单独的div中,并对删除按纽的onclick事件进行响应,使之删除删除按纽所在的div。

·如:this.parentNode.parentNode.removeChild(this.parentNode);

*3 显示下载文件列表

a)递归方式查询可供下载的文件,一定要有出口条件

b)使用Map收集可供下载的文件

c)使用和

*4 下载文件

a)对传过来的中文编码进行URL解码

b)通过UUID文件名,反向查到该文件所在的真实目录

5 文件上传下载与数据库结合

a)在将上传文件保存的同时,写往数据库表,一个上传文件对应一条记录,确保uuidFileName双方一致

思考:

a)上传时,先硬盘,再表?

b)下载时,先硬盘,再表?

c)删除时,先硬盘,再表?

d)是否需要事务支持?

Tip:文件下载

Web应用中实现文件下载的两种方式

·超链接直接指向下载资源

·程序实现下载需设置两个响应头:

·设置Content-Type 的值为:application/x-msdownload。Web 服务器需要告诉浏览器其所输出的内容的类型不是普通的文本文件或 HTML 文件,而是一个要保存到本地的下载文件。

·Web 服务器希望浏览器不直接处理相应的实体内容,而是由用户选择将相应的实体内容保存到一个文件中,这需要设置 Content-Disposition 报头。该报头指定了接收程序处理数据内容的方式,在 HTTP 应用中只有 attachment 是标准方式,attachment 表示要求用户干预。在 attachment 后面还可以指定 filename 参数,该参数是服务器建议浏览器将实体内容保存到文件中的文件名称。在设置 Content-Dispostion 之前一定要指定 Content-Type.

·因为要下载的文件可以是各种类型的文件,所以要将文件传送给客户端,其相应内容应该被当做二进制来处理,所以应该调用 方法返回 ServletOutputStream 对象来向客户端写入文件内容。

package cn.itcast.web.servlet.download;

import java.io.File;

import java.io.IOException;

import java.util.HashMap;

import java.util.Map;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import cn.itcast.web.servlet.util.UploadUtil;

//显示可供下载的文件列表

public class ListFileServlet extends HttpServlet {

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

//定位下载文件的目录

String uploadPath = this.getServletContext().getRealPath(UploadUtil.uploadPath);

//创建Map

Map map = new HashMap();

//取得下载文件的相关信息

getFiles(uploadPath,map);

//转发到list.jsp显示可供下载的文件

request.setAttribute("map",map);

request.getRequestDispatcher("/WEB-INF/list.jsp").forward(request,response);

}

//递归询查所有可供下载的文件

private void getFiles(String uploadPath , Map map){

File file = new File(uploadPath);

//如果file表示文件

if(file.isFile()){//出口//取得文件名,即UUID文件名

String uuidFileName = file.getName();

int index = uuidFileName.indexOf("_");

String realFileName = uuidFileName.substring(index+1);

//存放到Map集合中

map.put(uuidFileName,realFileName);

}else{

//必定是目录//取得该目录下的所有内容

File[] files = file.listFiles();

for(File f : files){

//递归调用自已

getFiles(f.getPath(),map);

}

}

}

}

下载文件列表文件名操作${entry.value}

下载

package cn.itcast.web.servlet.download;

import java.io.FileInputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.URLEncoder;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import cn.itcast.web.servlet.util.UploadUtil;

//下载文件到本地

public class DownloadServlet extends HttpServlet {

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

String uuidFileName = request.getParameter("uuidFileName");

byte[] buf = uuidFileName.getBytes("ISO8859-1");

uuidFileName = new String(buf,"UTF-8");

int index = uuidFileName.lastIndexOf("_");

String realFileName = uuidFileName.substring(index+1);

response.setHeader("content-disposition","attachment;filename="+URLEncoder.encode(realFileName,"UTF-8"));

String uploadPath = this.getServletContext().getRealPath(UploadUtil.uploadPath);

String uuidFilePath = UploadUtil.makeUuidFilePath(uploadPath,uuidFileName);

InputStream is = new FileInputStream(uuidFilePath+"/"+uuidFileName);

//模式:/WEB-INF/upload/12/4/43213_cc.jpg

OutputStream os = response.getOutputStream();

buf = new byte[1024];

int len = 0;

while((len=is.read(buf))>0){

os.write(buf,0,len);

}

is.close();

os.close();

}

}

*1 文件上传下载和数据库结合

1)速度:较小文件的文件存入数据库中,取出速度较快,返之较慢。

较大文件的存入硬盘中,取出速度相对于数据库较快。

2)同步:

数据库表和硬盘必须一致,必须要事务的支持

在事务的情况下,表操作优先,硬盘其后

package cn.itcast.web.servlet.domain;

public class Up {

private int id;

private String username;

private String realFileName;

private String uuidFileName;

public Up(){}

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getUsername() {

return username;

}

public void setUsername(String username) {

this.username = username;

}

public String getRealFileName() {

return realFileName;

}

public void setRealFileName(String realFileName) {

this.realFileName = realFileName;

}

public String getUuidFileName() {

return uuidFileName;

}

public void setUuidFileName(String uuidFileName) {

this.uuidFileName = uuidFileName;

}

}

package cn.itcast.web.servlet.dao;

import java.sql.SQLException;

import org.apache.commons.dbutils.QueryRunner;

import cn.itcast.web.servlet.domain.Up;

import cn.itcast.web.servlet.util.JdbcUtil;

public class UpDao {

//增加Up对象

public void addUp(Up up) throws SQLException{

QueryRunner runner = new QueryRunner(JdbcUtil.getDataSource());

String sql = "insert into up(username,realFileName,uuidFileName) values(?,?,?)";

runner.update(sql,new Object[]{up.getUsername(),up.getRealFileName(),up.getUuidFileName()});

}

}

com.mysql.jdbc.Driver

root

root

jdbc:mysql://127.0.0.1:3306/mydb3

package cn.itcast.web.servlet.util;

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import com.mchange.v2.c3p0.ComboPooledDataSource;

//JDBC工具类:关闭流和取得连接

public final class JdbcUtil {

private static ComboPooledDataSource dataSource;

static{

dataSource = new ComboPooledDataSource();

}

//取得数据源

public static ComboPooledDataSource getDataSource() {

return dataSource;

}

//取得连接

public static Connection getMySqlConnection() throws SQLException{

return dataSource.getConnection();

}

//关闭连接

public static void close(Connection conn) throws SQLException{

if(conn!=null){

conn.close();

}

}

public static void close(PreparedStatement pstmt) throws SQLException {

if(pstmt!=null){

pstmt.close();

}

}

public static void close(ResultSet rs) throws SQLException {

if(rs!=null){

rs.close();

}

}

}

package cn.itcast.web.servlet.upload;

import java.io.IOException;

import java.util.ArrayList;

import java.util.List;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import cn.itcast.web.servlet.domain.Up;

import cn.itcast.web.servlet.domain.User;

import cn.itcast.web.servlet.exception.NoUpfileException;

import cn.itcast.web.servlet.exception.UpfileSizeException;

import cn.itcast.web.servlet.exception.UpfileTypeException;

import cn.itcast.web.servlet.service.UpService;

import cn.itcast.web.servlet.util.UploadUtil;

public class UploadServlet extends HttpServlet {

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

try {

User user = UploadUtil.doUpload(request);

String uploadPath = this.getServletContext().getRealPath(UploadUtil.uploadPath);

List upList = new ArrayList();

//写入硬盘

UploadUtil.doSave(user,uploadPath,upList);

//写入数据库表

UpService upService = new UpService();

upService.addUps(upList);

request.setAttribute("message","上传文件成功");

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

}catch(UpfileSizeException e){

e.printStackTrace();

request.setAttribute("message","上传文件大小限制在200K以内");

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

}catch(UpfileTypeException e){

e.printStackTrace();

request.setAttribute("message","只能上传JPG格式的文件");

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

}catch(NoUpfileException e){

e.printStackTrace();

request.setAttribute("message","无上传文件");

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

}catch (Exception e) {

e.printStackTrace();

request.setAttribute("message","上传文件失败");

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

}

}

}

利用mysql实现上传和下载_文件上传表单 上传文件的细节 文件上传下载和数据库结合...相关推荐

  1. 前端_网页编程 Form表单与模板引擎(上)

    目录 一.form表单的基本使用 1. 什么是表单? 2. 表单的组成部分 3. < form>标签的基本属性 3.1 action 3.2 target 3.3 method 3.4 e ...

  2. vue - element <upload> 组件批量上传文档,可携带其他表单数据项一同与文件 “手动提交“ 服务器(类似百度文库系统批量上传前端界面与逻辑)超详细教程示例源码,提供界面与逻辑完整源码

    效果图 本示例使用的是 element 组件库,其实什么组件库都行(逻辑是一样),只要你是 vue.js 项目就能使用本教程. 本文实现了 vue + element 使用 upload 组件批量上传 ...

  3. 前端_网页编程 Form表单与模板引擎(中)

    目录 ... ... (续上篇) 四.模板引擎的基本概念 1.定义 2. 优点 五.art-template模板引擎 1.art-template模板引擎介绍 2. art-template的安装 3 ...

  4. 前端_网页编程 Form表单与模板引擎(下)

    目录 续上一篇 6. 模板引擎的实现原理 6.1 正则与字符串操作 6.1.1 基本语法 6.1.2 分组 6.1.3 字符串的replace函数 6.1.4 多次replace 6.1.5 使用wh ...

  5. angular元素属性绑定_【Angular】表单

    模板式表单 表单数据模型通过组件模板中的相关指令定义,但是只适用于一些简单的场景.比较死板 指令:来自FormsModule模块中 在app.modules.ts中 import { FormsMod ...

  6. nginx delete form表单 收不到参数_HTTP 文件上传的一个后端完善方案(NginX)

    (给PHP开发者加星标,提升PHP技能) 转自:林伯格 https://breeze2.github.io/blog/scheme-nginx-php-js-upload-process 前言 很多网 ...

  7. android multipartentity 怎么上传参数,android-通过MultipartEntityBuilder通过HTTP表单上传文件,并显示进度b...

    android-通过MultipartEntityBuilder通过HTTP表单上传文件,并显示进度b 短版本-.jar已弃用,其升级版本java.lang.NoClassDefFoundError在 ...

  8. aspx文件上传表单内容到另一个aspx文件,但后续文件无法显示出接收到的信息,大佬们该咋办

    我建立了两个aspx文件,其中一个为填写表单信息的网站,在填写完成后点击提交就会将表单信息上传到第二个asox文件中,并且在该网站的界面中显示出来.但并没有,试过了多个浏览器,代码也基本没问题.求助各 ...

  9. php无表单上传文件,php – 来自表单的WP邮件附件,无文件管理器上传文件

    从表单通过wp_mail函数我正在尝试发送带附件的电子邮件,而不将文件上传到文件管理器. 我收到附件的电子邮件.但附件名称不正确,没有文件类型.请帮忙解决这个问题. 这是HTML表单 有我的PHP代码 ...

  10. javascript构造可以上传文件的form表单(通过js修改enctype)

    在上传文件时,我们都知道需要在form表单中加上enctype="multipart/form-data".而在开发过程中,也有可能遇到需要用javascripts构造form表单 ...

最新文章

  1. java杀死自身并重启_java – android服务在应用程序被杀死时自动重启
  2. C 中 main 函数的参数
  3. Java 调用存储过程 返回结果集
  4. JZOJ 4675. 【NOIP2016提高A组模拟7.21】Double-row
  5. 如何自动填充网页表单_iCab for Mac(web网页浏览器)
  6. linux shell学习四
  7. 关于远程访问tomcat问题的总结
  8. 【c语言课程设计】C语言校园卡管理系统
  9. android listener使用实例,如何使用lambda表达式/缩短onclicklisteners android studio(示例代码)...
  10. 鸿蒙大陆9.1正式版礼包,鸿蒙大陆2.0正式版
  11. java常量 修改_Java 自定义常量
  12. photoshop切片的使用
  13. 互联网思维和项目管理
  14. 1453 : 当小偷遇见了悍匪
  15. java企业员工出差报销预算管理系统-SSH-Mysql
  16. 风影ASP.NET基础教学 2 web服务器控件
  17. linux下socket编程(基础参考)
  18. 第一阶段冲刺团队贡献值分析
  19. 手机sar值_主流手机SAR对比,辐射最大竟然是它
  20. 腾讯反360秘密会议

热门文章

  1. matlab求解外弹道,求解一个matlab弹丸质点外弹道的微分方程组
  2. A Inspire | FBI 特工告诉你如何读懂身边的同事
  3. 关于勒索病毒WannaCry的9个真相:小白如何防御?
  4. vue+node.js+moogodb仿王者荣耀移动端项目一
  5. ES6之Proxy代理
  6. 苹果8.1系统无服务器,苹果正式推出iOS8.1系统更新
  7. global 仪表控件 无人机地面站_基于GL Studio的无人机地面站天线控件设计与实现...
  8. 学校计算机的使用英语作文180字,我的梦想高中英语作文180字
  9. C++STL之vector
  10. 问大家一个问题,如何用1万元创业,每天利润达到500元?