文件上传
1.客户端编程
要上传文件,必须利用mutipart/form-data 设置HTML表单的enctype 属性值
如果想上传多个文件,则不得不使用文件input元素,在input元素加入multipel属性 ,以便生成一个按钮供选择多个文件
同样效果
2. 服务器端编程
Sevlet中的服务器处理上传文件的Servlet必须用 @MutipartConfig 进行标注。
MutipartConfig带有下面几个属性:
maxFileSize: 表示可上传文件的容量。默认为-1,表示不受限制
maxRequestSize:表示允许多部分HTTP请求的最大容量。默认为-1,表示不受限制
location:将上传的文件保存到磁盘中的指点位置,调用Part的write方法将用到它
fileSizeThreshold:设定一个溢出尺寸,超过这个值之后,上传的文件将被写入磁盘
在一个有多部分组成的请求中,标一个表单域,包括非文件域,都会被转换成一个Part
HttpServletRequest 接口定义了以下方法来处理多部分的请求:
Part getPart (String name) :返回指点名称的Part
Collection getParts() :返回这个请求的所有PART
Part接口还有以下的方法
String getName() 返回与指定部分有关的域名称,非文件名称(要想获取文件名称,需要解析content-disposition标头)
Collection getHeaderNames() 返回这个part中所有标头名称
String getContentType() 如果part是文件,则返回文件的名称,否则返回null (用于检验一个Part是否为文件域)
String getHeader(String name) 返回指点name的标头名称
Collection getHeaders(String name) 返回这个part中所有标头名称
void write(String path) 将上传的文件写入磁盘中。如果path是个绝对路径,则写入,如果path是相对路径,那么将被写入相对MultiConfig注解的location属性指定的路径
void delete() 删除该文件对应的储存
java.io.InputStream getInputStream() 以InputStream的形式返回上传文件的内容
如果上传一个名为document的note.txt文件时,其具有标头:
content-type:text/plain
content-disposition:form-data;name="document" ;filename="note.txt"
如果没有选择文件,还是会为该文件域创建一个Part,相关标头:
content-type:application/octet-stream
content-disposition:form-data;name="document" ;filename=""
对于非文件的域,Part只有content-disposition标头
3.实例:上传Servlet范例
下面例子示范如何编写一个多部分的Servlet。它可以处理单个文件上传
SingleUploadServlet类,实现MutipartConfig
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(urlPatterns={"/singleUpload"})
@MultipartConfig
public class SingleUploadServlet extends HttpServlet {
private static final long serialVersionUID=8593038L;
private String getFilename(Part part){
String contentDispositoinHeader=part.getHeader("content-disposition");
String [] elements=contentDispositoinHeader.split(";");
for(String element:elements){
if(element.trim().startsWith("filename")){
return element.substring(
element.indexOf('=')+1).trim().replace("\"", "");
}
}
return null;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
Part part=req.getPart("filename");
String fileName=getFilename(part);
if(fileName!=null&&!fileName.isEmpty()){
part.write(getServletContext().getRealPath("/WEB-INF")+"/"+fileName);
}
resp.setContentType("text/html");
PrintWriter writer=resp.getWriter();
writer.print("
Uploaded file name:"+fileName);
writer.print("
Size:"+part.getSize());
String author=req.getParameter("author");
writer.print("
Author:"+author);
}
singleUpload.jsp页面
Select a file to upload
与前一个例子相似,只不过它是遍历Part集合,努力核实Part是包含一个文件还是一个域值
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
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(urlPatterns={"/multipleUploads"})
@MultipartConfig
public class MultipleUploadsServlet extends HttpServlet {
private static final long serialVersionUID=9991L;
private String getFilename(Part part){
String contentDispositoinHeader=part.getHeader("content-disposition");
String [] elements=contentDispositoinHeader.split(";");
for(String element:elements){
if(element.trim().startsWith("filename")){
return element.substring(
element.indexOf('=')+1).trim().replace("\"", "");
}
}
return null;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
resp.setContentType("text/html");
PrintWriter writer=resp.getWriter();
Collection parts=req.getParts();
for(Part part:parts){
if(part.getContentType()!=null){
String fileName=getFilename(part);
if(fileName!=null&&!fileName.isEmpty()){
part.write(getServletContext().getRealPath("/WEB-INF")+"/"+fileName);
writer.print("
Uploader file name:"+fileName);
writer.print("
Size:"+part.getSize());
}
}else{
//假如不存在内容类型,则意味着Part表示的是一个非文件域
String partName=part.getName();
String filedValue=req.getParameter(partName);
writer.print("
"+partName+":"+filedValue);
}
}
}
}
Select a file to upload