本篇是servlet和jsp学习指南一书的示例代码加上自己理解,以及在写的过程中遇到的问题
servlet 4.0文档
javax.servlet.http.Part(Interface)
This class represents a part as uploaded to the server as part of a multipart/form-data request body. The part may represent either an uploaded file or form data.
自从servlet3.0开始就有了这个接口,该接口表示上传到服务器的multipart/form-data请求的主体部分。该部分可能是上传的文件或是表单数据
下面使用了write方法
void write(java.lang.String fileName) throws java.io.IOException
这是一种将上传的part写入磁盘的一种便捷方法。客户端代码并不关心该part是存储在内存中,还是在临时位置上的磁盘上。他们只是想把上传的部分写入文件。如果同一个part调用多次的write方法,则该方法不能保证成功。这允许特定的实现在可能的情况下使用文件重命名,而不是复制所有底层数据,从而获得显著的性能效益。(这句话不知道什么意思,猜测是可以通过进行文件重命名来赋值文件,而不是重新copy所有底层数据)
其中有个方法是servlet3.1新出的
java.lang.String getSubmittedFileName()返回上传文件的名字,若不存在则返回null,所以这里需要进行判断
上传单个文件
uploadfile.jsp页面
<%@ page contentType="text/html; charset=UTF-8"%>
<html>
<head>
<title>upload file</title>
</head>
<body>
<!-- enctype规定在发送到服务器之前应该如何对表单数据进行编码 -->
<!-- multipart/form-data不对字符编码,在使用包含文件上传控件的表单时,必须使用该值 -->
<form method="post" action="/ServletModel/model/UploadServlet" enctype="multipart/form-data">
作者: <input type="text" name="author"/><br/>
选择文件:
<input type="file" name="upload_file">
<input type="submit" value="上传"/>
</form>
<br/>${hint}
</body>
</html>
UploadServlet.java,servlet
package com.xck.model.servlet;
import java.io.IOException;
import java.io.PrintWriter;
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;
@WebServlet(name="UploadServlet", urlPatterns={"/model/UploadServlet"})
//说明该Servlet处理的是multipart/form-data类型的请求,是Servlet3.0提供的对文件上传的支持
@MultipartConfig
public class UploadServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{
//Servlet3.0中新引入的方法,用来处理multipart/form-data类型编码的表单
//可以用request.getPart("..")方法获得name为upload—_file的上传附件
//多文件上传request.getParts(),然后通过循环分别处理每一个上传附件
request.setCharacterEncoding("UTF-8");
//通过html标签name属性值获取
Part part = request.getPart("upload_file");
String fileName = getFileName(part);
if(fileName!=null && !fileName.isEmpty()){
String path = request.getServletContext().getRealPath("\\upload") + "\\" + fileName;
System.out.println(path);
part.write(path);
//响应 这里同样要设置编码
response.setContentType("text/html; charset=UTF-8");
PrintWriter writer = response.getWriter();
writer.print("<br/>Uploaded file name: " + fileName);
writer.print("<br/>file size: " + part.getSize());
String author = request.getParameter("author");
writer.print("<br/>author: " + author);
}else{
request.setAttribute("hint", "上传失败,上传文件名或路径有问题");
//这里若没有加上/会跳转到 /model/uploadfile.jsp多了个model
request.getRequestDispatcher("/uploadfile.jsp").forward(request, response);
}
}
/**
* 获取上传的文体名
* @param part
* @return 上传文件名
*/
private String getFileName(Part part){
if(part == null){
return null;
}
//Tomcat7下并没有getSubmittedFileName方法可以直接获取名字
//上传文件请求头中会有content-disposition
//获取请求头中的Content-Disposition,里面有表单信息,标签name属性值,filename上传文件的路径+文件名
/*
content-disposition example:
form-data; name="upload_file";
filename="D:\spring-framework-4.3.2.RELEASE-dist\spring-framework-4.3.2.RELEASE\libs\spring-webmvc-4.3.2.RELEASE-sources.jar"
*/
String contentDisposition = part.getHeader("Content-Disposition");
String[] elements = contentDisposition.split(";"); //以分号作为分隔符
for(String element : elements){
if(element.trim().startsWith("filename")){
//+1是为了跳过\,且字符串最后一个是引号,也要跳过,之前写的时候没注意,一直报错FileNoFound
return element.substring(element.lastIndexOf("\\")+1, element.length()-1);
}
}
return null;
}
}
还可以限制文件上传的大小和类型等功能。。