一:项目的框架
二:Web前端设计部分
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>文件上传页面</title> </head> <body> <!-- 1.文件的上传必须是post,因为post请求的数据是放在请求体中的,可以携带大量的数据 2.第二步enctype的值必须是:多媒体的表单数据,文件的上传必须要这个参数 --> <form method="post" enctype="multipart/form-data" action="file"> File:<input type="file" name="avatar"><br> <input type="submit"> </form> </body> </html>
效果如下:
三:Servlet设计部分
//这是一个用来上传文件到服务器的servlet package com.whx.servlet; import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerOutputVisitor; 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.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.util.UUID; @WebServlet(value="/file" , name="FileServlet") @MultipartConfig //这是告诉servlet,你处理的是一个多媒体表单数据 public class FileServlet extends HttpServlet { //定义文件上传之后 保存的路径的目录 private String fileLocation = "E:\\nginx\\nginx-1.17.2\\html\\"; //定义 private String fileServer ="Http://localhost/"; @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //设置上传文件的默认编码方式 req.setCharacterEncoding("utf-8"); //获取上传的文件的所有的信息,part中封装了要上传的文件的所有信息 Part part = req.getPart("avatar"); System.out.println(part); //=============获取上传的文件的文件名(目的是可以补充到保存文件的路径当中,构成一个完整的路径)====================== //注意: part.getName(): 获取的 !!!并不是文件的名字 // 要获取文件的名字, 文件名是存储在Part的头部的"content-disposition"中 // 所以要想获取文件的名字,必须要先获取文件的头部(参数中填 content-disposition) // eg: contentDisposition的数据内容是: form-data; name="avatar"; filename="4月8日复习.txt" String contentDisposition = part.getHeader("content-disposition"); // 下一步是要从contentDisposition中获取filename的内容 //1. String filePrefix = "filename=\""; // \"为转义字符 //2. 获取文件名开始位置所在的索引 int index = contentDisposition.indexOf(filePrefix) + filePrefix.length(); //3.获取文件名 contentDisposition.length()-1 的原因是 因为最后有个" String fileName = contentDisposition.substring(index, contentDisposition.length() - 1); //4.获取文件的后缀名: .png .txt .jpg String fileSuffix = fileName.substring(fileName.indexOf(".")); //5.为了避免上传的文件会有因为重名而导致保存失败的事件的发生 那么我们可以随机生成一个字符串来给上传的文件命名 String newFileName = UUID.randomUUID().toString() + fileSuffix; // 利用part获取文件的输入流 InputStream is = part.getInputStream(); //获取文件输出流 (输出流的目标是:文件保存的路径) fileLocation是上传文件默认的保存目录 newFileName是上传的文件的新的名字 FileOutputStream os = new FileOutputStream(fileLocation + newFileName); //存储IO流每次读取的数据 byte[] bs = new byte[1024]; //每次读取的有效数字 int length = 0; //读取上传文件的同时 往服务器本地保存文件数据 while ( -1 != ( length = is.read(bs))){ os.write(bs,0,length); } //读取完毕 释放资源 os.flush(); os.close(); is.close(); // ==============================以下是服务器对html页面请求的回应============================================ //设置页面的默认编码方式 resp.setContentType("text/html;charset=utf-8"); //获取输出流 PrintWriter writer = resp.getWriter(); //获取StringBuffer进行html语句的拼接 StringBuffer html = new StringBuffer(); html.append("<html>") .append("<head></head>") .append("<body><h1>上传成功</h1>") // fileServer + newFileName = http://localhost/0dc725b1-5b12-4865-bbd0-2fbed66b9e7e.png .append("<img src=\"" + fileServer + newFileName + "\">") //.append("<video src=\"" + fileServer + newFileName + "\" width=\"600\" height=\"400\" autoplay>") .append("</body></html>"); writer.write(html.toString()); writer.flush(); writer.close(); } }
四:注意事项
(1)HTML:
1.文件上传的方法必须是post,因为get的大小有限而post请求的数据是放在请求体重的,可以携带大量的数据
2.enctype的值必须是: multipart/form-data :多媒体表单数据,文件的上传必须是这个参数
3.action中的值必须得和servlet中的注释WebServlet中的value的值对应起来,两者必须取名相同
action中的值不加"/"表示这是相对路径
4.文件上传,type为"file"的input标签中name的值要与servlet获取文件信息的getPart方法的参数联系起来
(2)Servlet:
1.文件上传必须要有两个注解: 一个是WebServlet(这个中value的值是用来和HTML页面action的值绑定起来的)
另一个是MultipartConfig 这个是标记这个Servlet处理的是一个多媒体表单数据
2.文件上传需要获取: 上传文件的信息: 文件的名字 文件的后缀名
文件的信息可以通过getPart(参数)方法获取;
文件的名字存放在文件的头部中,文件的头部信息,可以通过getHeader(参数)获取 参数是"content-disposition";
通过文件的头部信息,可以通过字符串类的api来截取
(3)编码问题
1.设置上传文件的默认编码方式
//设置上传文件的默认编码方式 req.setCharacterEncoding("utf-8");
2.设置文件输出到HTML页面的默认编码方式
resp.setContentType("text/html;charset=utf-8");