文件上传
1.文件上传三要素
a. 表单项input的type属性必须是file;
input表单项的type必须是file,因为只有这样,才能选择本地的文件
b. form表单的method属性必须是post;
文件上传时,向服务器传递的数据一般都比较大,而get请求的请求参数限制为4kb,所以这里提交方式必须是post请求。
c. form表单的enctype属性值必须是 multipat/form-data;
form表单的enctype属性是用来规定表单项的内容格式,默认值是 application/x-www-form-urlencoded,如果需要上传文件,必须把enctype属性值设置为 multipart/form-data,这样文件的内容才会被上传到服务器上。
enctype属性是用来规定,form表单范围内的表单项的数据应该按照什么样的格式传递给服务器;
当form表单的enctype属性是application/x-wwww-form-urlencoded(默认),传递的内容如下:
username=zhangsan&file1=config.txt
当form表单的enctype属性是multipat/form-data传递的数据内容格式如下:
username=zhangsan&file1=config.txt
-----------------------------18467633426500
Content-Disposition: form-data; name="username"
zhangsan
-----------------------------18467633426500
Content-Disposition: form-data; name="file1"; filename="config.txt"
Content-Type: text/plain
你大舅你二舅都是你舅,走一步退一步等于么走
-----------------------------18467633426500--
2.fileupload组件完成文件上传
fileUpload是apache的commons组件提供的上传组件,提供了方便的API让我们可以很方便的得到浏览器上传的文件内容。
使用fileUpload组件首先需要引入两个jar包:
- commons-fileUpload.jar
- commons-io.jar
fileUpload的核心类有DiskFileItemFactory、ServletFileUpload、FileItem。
如果要通过fileupload组件,完成文件上传,可以参照文档:https://blog.csdn.net/linghuainian/article/details/82253247
3.Servlet3.0完成文件上传(基于fileupload组件完成)
从servlet3.0规范开始,提供了方便的API可以让我们解析浏览器传递的文件内容。
完成步骤:
1.在接收请求的Servlet上添加 @MultipartConfig 注解,标识该Servlet会接收文件内容;
2.通过 request.getPart(“文件参数名”) 得到一个Part对象,该对象封装了文件表单项相关的所有内容;
**// 3.在tomcat7 的环境下就没有part.getSubmittedFileName()这一方法,无法直接获取文件名
String cd = myFile.getHeader("Content-Disposition");
//截取不同类型的文件需要自行判断
String fileName = cd.substring(cd.lastIndexOf("=")+2, cd.length()-1);**
//3.通过 part对象.getSubmittedFileName() 可以得到文件的名称;
4.通过 part对象.getInputStream() 可以得到流对象,读取文件的内容;
5.通过 输出流,把文件的内容输出到服务器本地文件中。
// servlet
package live.longmarch.web.servlet;
import javax.servlet.ServletContext;
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 java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* 定义表单提交的servlet
* 注意, fileupload组件完成文件上传
* Servlet3.0完成文件上传(基于fileupload组件完成)
* 1.在接收请求的Servlet上添加 **@MultipartConfig** 注解,标识该Servlet会接收文件内容;
*/
@MultipartConfig
@WebServlet("/uploadServlet")
public class UploadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 告诉浏览器发送什么样格式的请求参数
request.setCharacterEncoding("utf-8");
// 2.通过 **request.getPart("文件参数名")** 得到一个Part对象,该对象封装了文件表单项相关的所有内容;
Part myFile = request.getPart("myFile");
// 3.在tomcat7 的环境下就没有part.getSubmittedFileName()这一方法,无法直接获取文件名
String cd = myFile.getHeader("Content-Disposition");
//截取不同类型的文件需要自行判断
String fileName = cd.substring(cd.lastIndexOf("=")+2, cd.length()-1);
// System.out.println(filename);
/*
// 3.通过Part对象的getSubmittedFileName 可以得到文件的名称;
String fileName = myFile.getSubmittedFileName();*/
// 4.可以通过Part对象的方法getInputStream 获取读取文件的字节流
InputStream is = myFile.getInputStream();
// 5.创建ServletContext 对象 ,获取当前目录的绝对路径。将读取到的文件再写到当前目录下
ServletContext context = request.getServletContext();
String realPath = context.getRealPath("/");
// 6.定义一个path路径来拼接真实路径及文件名
String path = realPath + "/" + fileName;
File file = new File(path);
// 7.创建输出流写入数据,进行流的对拷
FileOutputStream fos = new FileOutputStream(file);
byte[] bytes = new byte[1024];
int len;
while ((len = is.read(bytes)) != -1){
fos.write(bytes,0,len);
}
String username = request.getParameter("username");
System.out.println(username);
// 释放资源
fos.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--定义表单
注意事项。如果要进行文件的上传,
1.需要设置为post请求,因为get请求只能发送较小的文件数据
2.enctype 的值需要设置为 multipart/form-data
3.<input type="file" name="myFile"> type为file才能实现上传文件的按钮
**a. 表单项input的type属性必须是file;**
input表单项的type必须是file,因为只有这样,才能选择本地的文件
**b. form表单的method属性必须是post;**
文件上传时,向服务器传递的数据一般都比较大,而get请求的请求参数限制为4kb,所以这里提交方式必须是post请求。
**c. form表单的enctype属性值必须是 multipat/form-data;**
form表单的enctype属性是用来规定表单项的内容格式,默认值是 application/x-www-form-urlencoded,如果需要上传文件,必须把enctype属性值设置为 multipart/form-data,这样文件的内容才会被上传到服务器上。
enctype属性是用来规定,form表单范围内的表单项的数据应该按照什么样的格式传递给服务器;
-->
<form action="uploadServlet" method="post" enctype="multipart/form-data">
<label>姓名:</label> <input type="text" name="username"><br>
<input type="file" name="myFile"><br>
<input type="submit" value="上传">
</form>
</body>
</html>
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>live.longmarch</groupId>
<artifactId>upload</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<!--servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<!--maven插件-->
<plugins>
<!--jdk编译插件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>utf-8</encoding>
</configuration>
</plugin>
<!--tomcat插件-->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<!-- tomcat7的插件, 不同tomcat版本这个也不一样 -->
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<!-- 通过maven tomcat7:run运行项目时,访问项目的端口号 -->
<port>80</port>
<!-- 项目访问路径 本例:localhost:9090, 如果配置的aa, 则访问路径为localhost:9090/aa-->
<path>/</path>
<!--在告诉timcat,使用utf-8对get请求传递的参数进行解码-->
<uriEncoding>utf-8</uriEncoding>
</configuration>
</plugin>
</plugins>
</build>
</project>