使⽤IDEA实现⽂件上传
1、⽂件上传
⽂件上传的注意事项:
1. 为保证服务器的安全,上传⽂件应该放在外界⽆法直接访问的⽬录下,⽐如放于WEB-INF⽬录下
2. 为防⽌⽂件覆盖的现象发⽣,要为上传⽂件产⽣⼀个唯⼀的⽂件名(可使⽤-时间戳,-uuid,-MD5,-位运算加密算法等)
3. 要限制上传⽂件的最⼤值
4. 可以限制上传⽂件的类型,在收到上传⽂件名时,判断后缀名是否合法(可限制为.mp4,.txt,.,.jpg,.png,.)
需要⽤到的类详解:
ServletFileUpload负责处理上传的⽂件数据,并将表单中每个输⼊项封装成⼀个FileItem对象,在使⽤Ser
vletFileUpload对象解析请求时,需要DiskFileItemFactory对象。所以,我们需要在进⾏解析⼯作前构造好DiskFileItemFactory对象,通过ServletFileUpload对象的构造⽅法或setFileItemFacotry()⽅法设置ServletFileUpload对象的fileItemFactory属性。
Tomcat项⽬发布路径:
D:\environment\apache-tomcat-9.0.58-windows-x64\apache-tomcat-9.0.58\webapps\t9
项⽬代码:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="/POM/4.0.0" xmlns:xsi="/2001/XMLSchema-instance"
xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.kuang</groupId>
<artifactId>file</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>6</source>
<target>6</target>
</configuration>
</plugin>
</plugins>
</build>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--Servlet 依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<!--JSP依赖-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<!--standard标签库-->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<!--JSTL表达式的依赖-->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!--连接数据库-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<!-- mvnrepository/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.79</version>
</dependency>
<!-- mvnrepository/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<!-- mvnrepository/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
</dependencies>
</project>
======================================================================================
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
======================================================================================
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<%--通过表单上传⽂件
get: 上传⽂件⼤⼩有限制
post: 上传⽂件⼤⼩没有限制
--%>
<%--${tPath}获取服务器路径/file/index--%>
<form action="${tPath}/upload.do" enctype="multipart/form-data" method="post">上传⽤户:<input type="text" name="username"><br/>
<p><input type="file" name="file1"></p>
<p><input type="file" name="file1"></p>
<p><input type="submit"> | <input type="reset"></p>
</form>
</body>
</html>
html实现用户注册登录代码public class FileServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //判断上传的⽂件是普通表单还是带⽂件的表单
if (!ServletFileUpload.isMultipartContent(request)){
return; //中⽌⽅法运⾏,说明这是⼀个普通的表单,直接返回
}
//创建上传⽂件的保存路径,建议在WEB-INF路径下,安全,⽤户⽆法直接访问上传的⽂件;
String uploadPath = ServletContext().getRealPath("/WEB-INF/upload");
File uploadFile = new File(uploadPath);
if (!ists()){
uploadFile.mkdir(); //创建这个⽬录
}
//缓存,临时⽂件
//临时路径,假如⽂件超过了预期的⼤⼩,我们就把他放到⼀个临时⽂件中,过⼏天⾃动删除,或者提醒⽤户转存为永久 String tmpPath = ServletContext().getRealPath("/WEB-INF/tmp");
File file = new File(tmpPath);
if (!ists()){
file.mkdir(); //创建这个临时⽬录
}
/
/处理上传的⽂件,⼀般都需要通过流来获取,我们可以使⽤InputStream(),原⽣态的⽂件上传流获取,⼗分⿇烦
//但是我们都建议使⽤Apache的⽂件上传组件来实现,common-fileupload,它需要依赖于commons-io组件;
/*
ServletFileUpload负责处理上传的⽂件数据,并将表单中每个输⼊项封装成⼀个FileItem对象,
在使⽤ServletFileUpload对象解析请求时需要DiskFileItemFactory对象。
所以,我们需要在进⾏解析⼯作前构造好DiskFileItemFactory对象,
通过ServletFileUpload对象的构造⽅法或setFileItemFactory()⽅法设置ServletFileUpload对象的fileItemFactory属性。
*/
try {
/
/1.创建DiskFileItemFactory对象,处理⽂件上传路径或者⼤⼩限制的;
DiskFileItemFactory factory = getDiskFileItemFactory(file);
//2.获取ServletFileUpload
ServletFileUpload upload = getServletFileUpload(factory);
//3.处理上传⽂件
String msg = uploadParseRequest(upload,request,uploadPath);
//servlet请求转发消息
request.setAttribute("msg",msg);
} catch (FileUploadException e) {
e.printStackTrace();
}
}
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() {
@Override
//pBytesRead(l):已经读取到的⽂件⼤⼩
//pContentLength(l1):⽂件⼤⼩
public void update(long l, long l1, int i) {
System.out.println("总⼤⼩:"+l1+"已上传:"+l);
}
});
//处理乱码问题
upload.setHeaderEncoding("UTF-8");
/
/设置单个⽂件的最⼤值
upload.setFileSizeMax(1024 * 1024 * 10);
//设置总共能够上传⽂件的⼤⼩
//1024 = 1kb * 1024 = 1M * 10 = 10M
upload.setSizeMax(1024 * 1024 * 10);
return upload;
}
public static String uploadParseRequest(ServletFileUpload upload,HttpServletRequest request,String uploadPath) throws FileUploadException, IOException{ String msg = "";
//把前端请求解析,封装成⼀个FileItem对象,需要从ServletFileUpload对象中获取
List<FileItem> fileItems = upload.parseRequest(request);
//fileItem 每⼀个表单对象
for (FileItem fileItem : fileItems) {
//判断上传的⽂件是普通的表单还是带⽂件的表单
if (fileItem.isFormField()){
//getFieldName指的是前端表单控件的name;
String name = FieldName();
String value = String("UTF-8");//处理乱码
System.out.println(name+":"+value);
}else { //⽂件
//================================处理⽂件=============================//
String uploadFileName = Name();
//可能存在⽂件名不合法的情况
if (im().equals("")||uploadFileName==null){
continue;
}
//获得上传的⽂件名 /images/girl/paojie.png
String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1);
//获得⽂件的后缀名
String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
/*
如果⽂件后缀名 fileExtName 不是我们所需要的
就直接return,不处理,告诉⽤户⽂件类型不对。
*/
System.out.println("⽂件信息[⽂件名:"+fileName+"---⽂件类型"+fileExtName+"]");
//可以使⽤UUID(唯⼀识别的通⽤码),保证⽂件名唯⼀;
//UUID.randomUUID(),随机⽣成⼀个唯⼀识别的通⽤码;
//⽹络传输中的东西,都需要序列化
//POJO ,实体类,如果想要在多个电脑上运⾏,传输===>需要把对象都序列化了
// JNI = Java Native Interface
//implements Serializable : 标记接⼝,JVM会识别,如果实现了该接⼝则会进⾏⼀些操作
//JVM---> Java栈本地⽅法栈 native--->C++
String uuidPath = UUID.randomUUID().toString();
//===============================存放地址==============================// //存到哪? uploadPath
//⽂件真实存在的路径 realPath
String realPath = uploadPath + "/" + uuidPath;
//给每个⽂件创建⼀个对应的⽂件夹
File realPathFile = new File(realPath);
if (!ists()){
realPathFile.mkdir();
}
//===============================⽂件传输==============================// //获得⽂件上传的流
InputStream inputStream = InputStream();
//创建⼀个⽂件输出流
//realPath = 真实的⽂件夹;
//查了⼀个⽂件;加上输出⽂件的名字+"/"+uuidFileName
FileOutputStream fos = new FileOutputStream(realPath + "/" + fileName);
//创建⼀个缓冲区
byte[] buffer = new byte[1024*1024];
//判断是否读取完毕
int len = 0;
//如果⼤于0说明还存在数据;
while ((ad(buffer))>0){
fos.write(buffer,0,len);
}
//关闭流
fos.close();
inputStream.close();
msg = "⽂件上传成功!";
fileItem.delete();//上传成功,清除临时⽂件
//=============================⽂件传输完毕=========================//
}
}
return msg;
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论