Servlet实现文件上传详解与实战

    文件上传


1.客户端编程


要上传文件,必须利用mutipart/form-data 设置HTML表单的enctype 属性值

Select a file


如果想上传多个文件,则不得不使用文件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

Author:
Select a file to upload





4.多文件上传

与前一个例子相似,只不过它是遍历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); } } } }


multipelUploads.jsp

    

Select a file to upload

Author:
First file to upload
Second file to upload



你可能感兴趣的:(JSP和Servlet学习指南)