博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JavaWeb中文件的上传
阅读量:3965 次
发布时间:2019-05-24

本文共 9984 字,大约阅读时间需要 33 分钟。

文件的上传和下载,是非常常见的功能。很多的系统中,或者软件中都经常使用文件的上传和下载。

比如:QQ 头像,就使用了上传。 邮箱中也有附件的上传和下载功能。 OA 系统中审批有附件材料的上传

文件的上传介绍(*****重点)

1、要有一个 form 标签,method=post 请求

2、form 标签的 encType 属性值必须为 multipart/form-data 值
3、在 form 标签中使用 input type=file 添加上传的文件
4、编写服务器代码(Servlet 程序)接收,处理上传的数据。
encType=multipart/form-data 表示提交的数据,以多段(每一个表单项一个数据段)的形式进行拼 接,然后以二进制流的形式发送给服务器
文件上传,HTTP 协议的说明
在这里插入图片描述

文件上传注意事项

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

• 2.为防止文件覆盖现象的发生,要为文件产生一个唯一的文件名 (添加时间戳 或者 uuid 或者MD5 或者位运算)
• 3.要限制上传文件的大小
• 4.可以限制上传文件的类型,在收到上传文件名时,要判断后缀名是否合格。
jsp文件:

    
用户名
头像

程序:

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletInputStream is = req.getInputStream(); byte[] buffer = new byte[1024000]; int len = is.read(buffer); System.out.println(new String(buffer,0,len));}

页面:

在这里插入图片描述
commons-fileupload.jar 常用 API 介绍说明
commons-fileupload.jar 需要依赖 commons-io.jar 这个包,所以两个包我们都要引入。
第一步,就是需要导入两个 jar 包:
commons-fileupload-1.2.1.jar
commons-io-1.4.jar
commons-fileupload.jar 和 commons-io.jar 包中,

我们常用的类有哪些?

ServletFileUpload 类,用于解析上传的数据。

FileItem 类,表示每一个表单项。
boolean ServletFileUpload.isMultipartContent(HttpServletRequest request); 判断当前上传的数据格式是否是多段的格式。
public List parseRequest(HttpServletRequestrequest) 解析上传的数据
boolean FileItem.isFormField() 判断当前这个表单项,是否是普通的表单项。还是上传的文件类型。 true 表示普通类型的表单项 false 表示上传的文件类型
String FileItem.getFieldName() 获取表单项的 name 属性值
String FileItem.getString() 获取当前表单项的值。
String FileItem.getName(); 获取上传的文件名
void FileItem.write( file ); 将上传的文件写到 参数 file 所指向抽硬盘位置 。

fileupload 类库的使用:

上传文件的表单:

    
用户名
头像

解析上传的数据的代码:

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1 先判断上传的数据是否多段数据(只是多段的数据,才是文件上传的 if(ServletFileUpload.isMultipartContent(req)){
// 创建FileItemFactory工厂实现类 FileItemFactory fileItemFactory= new DiskFileItemFactory(); // 创建用于解析上传数据的工具类ServletFileUpload类 ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory); try {
// 解析上传的数据,得到每一个表单项FileItem List
list = servletFileUpload.parseRequest(req); // 循环判断,每一个表单项,是普通类型,还是上传的文件 for(FileItem file : list){
// 普通表单项 if(file.isFormField()){
System.out.println("表单项的name属性值:" + file.getFieldName()); // 参数UTF-8.解决乱码问题 System.out.println("表单项的value属性值:" + file.getString("UTF-8")); }else{
// 上传的文件 System.out.println("表单项的name属性值:" + file.getFieldName()); System.out.println("上传的文件名:" + file.getName()); file.write(new File("." + file.getName())); } } } catch (Exception e) {
e.printStackTrace(); } } }}

结果:

在这里插入图片描述

在这里插入图片描述

上传文件模板(重点)

1.导包:

在这里插入图片描述

2.编写upload.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>    Title<%--		GET:上传文件大小有限制		POST:上传文件大小没有限制		 ${pageContext.request.contextPath}		 --%>
用户名:

3.web.xml

upload
com.loey.servlet.UpLoadFile
upload
/upload

4.编写servlet.java

package com.loey.servlet;import org.apache.commons.fileupload.FileItem;import org.apache.commons.fileupload.FileUploadException;import org.apache.commons.fileupload.ProgressListener;import org.apache.commons.fileupload.disk.DiskFileItemFactory;import org.apache.commons.fileupload.servlet.ServletFileUpload;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.util.List;import java.util.UUID;public class UpLoadFile extends HttpServlet {
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
if(!ServletFileUpload.isMultipartContent(req)){
//判断文件是带文件表单还是普通表单 return; //终止运行,说明这一定是一个不带文件的 } //为保证服务器安全,上传文件应该放在外界无法直接访问你得目录下,比如放在WEB-INF目录下 String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload"); File uploadFile = new File(uploadPath); if(!uploadFile.exists()){
uploadFile.mkdir();//创建目录 } // 创建一个临时目录,用来做临时缓存缓存 String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp"); File file = new File(tempPath); if(!file.exists()){
file.mkdir(); } String msg = null; // 处理上传的文件,一般都需要通过流来获取,我们可以使用 request, getInputstream(),原生态的文件上传流获取,十分麻烦 // 但是我们都建议使用 Apache的文件上传组件来实现, common-fileupload,它需要旅 commons-io组件; try {
//1.创建 DiskFileItemFactory,处理文件路径或者大小限制 DiskFileItemFactory factory = getDiskFileItemFactory(file); /* * //通过这个工厂设置一个缓冲区,当上传的文件大于这个缓冲区的时候,将他放到临时文件 factory.setSizeThreshold(1024 * * 1024); //缓存区大小为1M factory.setRepository (file);//临时目录的保存目录,需要一个File */ //2.获取ServletFileUpload ServletFileUpload upload = getServletFileUpload(factory); // 3.处理上传文件 // 把前端请求解析,封装成FileItem对象,需要从ServletFileUpload对象中获取 msg = uploadParseRequest(upload,req,uploadPath); } catch (FileUploadException e) {
e.printStackTrace(); } // 请求转发消息 req.setAttribute("msg",msg); req.getRequestDispatcher("/WEB-INF/info.jsp").forward(req,resp); } public static DiskFileItemFactory getDiskFileItemFactory(File file){
// 通过这个工厂设置一个缓冲区,当上传的文件大于这个缓冲区的时候,将他放到临时文件中; DiskFileItemFactory factory = new DiskFileItemFactory(); factory.setSizeThreshold(1024*1024); // 缓存区大小为1M factory.setRepository(file); // 临时目录的保存目录,需要一个file return factory; } public static ServletFileUpload getServletFileUpload(DiskFileItemFactory factory){
ServletFileUpload upload = new ServletFileUpload(factory); // 监听长传进度 upload.setProgressListener(new ProgressListener() {
// pBYtesRead:已读取到的文件大小 // pContextLength:文件大小 public void update(long pBytesRead, long pContenLength, int pItems) {
System.out.println("总大小:" + pContenLength + "已上传:" + (pBytesRead * 100 / pContenLength) + "%" ); } }); // 处理乱码问题 upload.setHeaderEncoding("UTF-8"); // 设置单个文件的最大值 upload.setFileSizeMax(1024*1024*10); // 设置总共能够上传文件的大小 upload.setSizeMax(1024*1024*10); return upload; } public static String uploadParseRequest(ServletFileUpload upload,HttpServletRequest req,String uploadPath) throws FileUploadException, IOException {
String msg = null; List
fileItems = upload.parseRequest(req); // 把前端请求解析,封装成一个FileItem对象 for (FileItem fileItem : fileItems) {
if (fileItem.isFormField()) {
// 普通表单 // getFieldName指的是前端表单控件的name; String name = fileItem.getFieldName(); String value = fileItem.getString("utf-8"); System.out.println(name + ":" + value); } else {
//判断是文件表单 // 拿到上传的文件路径 String uploadFileName = fileItem.getName(); // ===== 处理文件 ============= if (uploadFileName.trim().equals("") || uploadFileName == null) {
continue; } // 获得上传的文件名 String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1); //获得后缀 String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1); /* * 如果文件后缀名fileExtName不是我们所需要的 就直按return.不处理,告诉用户文件类型不对。 */ System.out.println("文件信息[件名: " + fileName + " ---文件类型" + fileExtName + "]"); // UUID.randomUUID() 随机生成一个唯一识别的通用码 // 网络中传输东西,都需要序列化 // POJO, 实体类, 如果想要生成在多个电脑上运行, 传输-->需要把对象都序列化 // JNI java native Interface // implements Serializable :标记接口 ,JVM --> Java栈 本地方法栈 native --> c++ String uuidPath = UUID.randomUUID().toString();// 可以 使用UUID(唯一识别的通用码),保证文件唯一 // 文件真实存在的路径realPath String realPath = uploadPath + "/" + uuidPath; // ================处理文件完毕============== // ========= 存放地址 ======== File realPathFile = new File(realPath); if (!realPathFile.exists()) {
realPathFile.mkdir(); } // ========= 文件传输 ======== // 获得文件上传的流 InputStream is = fileItem.getInputStream(); // 创建一个文件输出流 // realPath =真实的文件夹; // 差了一个文件;加上翰出文件的名产"/"+uuidFileName FileOutputStream fos = new FileOutputStream(realPath + "/" + fileName); // 创建一个缓冲区 byte[] buffer = new byte[1024]; int len = 0; //将文件写到要存放的地址的文件中 while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len); } fos.close(); is.close(); msg = "文件上传成功"; fileItem.delete(); //上传成功,清除临时文件 } } return msg; }}

5.编写info.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>    Title${msg}

结果:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述上传的文件在这个地方找:
在这里插入图片描述

转载地址:http://utuki.baihongyu.com/

你可能感兴趣的文章
onTouchEvent方法的使用
查看>>
Android详细解释键盘和鼠标事件
查看>>
Android设置默认Launcher
查看>>
Android判断GPS是否开启和强制帮用户打开GPS
查看>>
Android Studio中通过快捷键来提取提取方法
查看>>
和喜欢的女生聊天 15 分钟以后就找不到话题了怎么办?
查看>>
安卓4.0响应鼠标左右点击事件
查看>>
自定义dialog的布局样式
查看>>
android 之输入法
查看>>
Android4.0之后添加虚拟按键方法
查看>>
将自定义输入法设置为系统默认输入法
查看>>
Android Studio大课堂 - 6.2.打包 - 友盟多渠道包示例
查看>>
实用的欢迎页开源库 AppIntro
查看>>
Windows使用VNC viewer访问Ubuntu 14.04远程桌面的简单方法
查看>>
Android编译大全(六)
查看>>
TVS测试波形比较,让您更懂TVS
查看>>
yum安装对于下载总是失败的rpm包如何处理
查看>>
快速由PCI迁移到PCIe
查看>>
CCD和CMOS图像传感器的快门
查看>>
视频跟踪算法
查看>>