在Servlet3.0中使用request.getParts()获取上传文件

Servlet3.0新增了request.getParts()/getPart(String filename) api,用于获取使用multipart/form-data格式传递的http请求的请求体,通常用于获取上传文件。

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>图片上传</title>
<script>
	window.onload = function(){
			document.getElementById('fileUploader').onchange =
			function(){ 
				var file = document.getElementById('fileUploader').files[0];
				
				var	formData = new FormData(document.getElementById('imageForm'));
				//formData.append("imageFile",file);
				
				var httpRequest = new XMLHttpRequest();
				httpRequest.onreadystatechange = function(){
					if(httpRequest.readyState == 4 && httpRequest.status == 200){
						alert("结果: "+httpRequest.responseText);
					}
				};
				httpRequest.open("post","http://localhost:8080/aos-maintain/imageProcess.jsp",true);
				//httpRequest.setRequestHeader("Content-type","multipart/form-data");
				httpRequest.send(formData);
			}
	};
</script>
</head>
<body>

	<form id="imageForm" enctype="multipart/form-data" method="post">
		<input id="fileUploader" name="fileUploader" type="file" multiple/>
	</form>
</body>
</html>


 

上面的代码是一个上传文件的前台页面,选择文件后出发onchange事件,进行文件上传。

如图选择了三个文件,查看http请求体的格式,如下:

可见multipart/form-data格式的请求体将上传数据分成了多个结构相同的部分,“--”开头的一长串字符为浏览器生成的分隔符,请求体最后以两个“--”包裹的字符串作为结束标识,Content-Dispostion指明了当前part的数据对应的控件名,如果是文件,还会指出文件名。

 

package com.test.servlet;

import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
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;
@MultipartConfig
@WebServlet("/imageProcess.jsp")
public class ImageProcessPrimitiveServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public ImageProcessPrimitiveServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	
		System.out.println("request.getContentType(): " + request.getContentType());
		
		if(!request.getContentType().split(";")[0].equals("multipart/form-data"))
			return;
		
		Collection<Part> parts = request.getParts();
		System.out.println(parts);
		for(Part part:parts){
			System.out.println(part);
			FileProcess(part);
		}
		
		response.getWriter().print("end");
	}

	private void FileProcess(Part part) throws IOException {
		System.out.println("part.getName(): " + part.getName());
		
		if(part.getName().equals("fileUploader")){
			String cd = part.getHeader("Content-Disposition");
			String[] cds = cd.split(";");
			String filename = cds[2].substring(cds[2].indexOf("=")+1).substring(cds[2].lastIndexOf("//")+1).replace("\"", "");
			String ext = filename.substring(filename.lastIndexOf(".")+1);
			
			System.out.println("filename:" + filename);
			System.out.println("ext:" + ext);
			
			InputStream is = part.getInputStream();
			
			if(Arrays.binarySearch(ImageIO.getReaderFormatNames(),ext) >= 0)
				imageProcess(filename, ext, is);
			else{
				commonFileProcess(filename, is);
			}
				
			
			
		}
	}

	private void commonFileProcess(String filename, InputStream is) {
		FileOutputStream fos = null;
		try{
			fos=new FileOutputStream(new File(getClass().getResource("/").getPath()+filename));
			int b = 0;
			while((b = is.read())!=-1){
				fos.write(b);
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			try{
				fos.close();
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	}

	private void imageProcess(String filename, String ext, InputStream is) throws IOException {
		Iterator<ImageReader> irs = ImageIO.getImageReadersByFormatName(ext);
		ImageReader ir = irs.hasNext()?irs.next():null;
		if(ir == null) 
			return;
		ir.setInput(ImageIO.createImageInputStream(is));//必须转换为ImageInputStream,否则异常
		
		ImageReadParam rp = ir.getDefaultReadParam();
		Rectangle rect = new Rectangle(0,0,200,200);
		rp.setSourceRegion(rect);
		
		int imageNum = ir.getNumImages(true);//allowSearch必须为true,否则有些图片格式imageNum为-1。
		
		System.out.println("imageNum:" + imageNum);
		
		for(int imageIndex = 0;imageIndex < imageNum;imageIndex++){
			BufferedImage bi = ir.read(imageIndex,rp);
			ImageIO.write(bi, ext, new File(getClass().getResource("/").getPath()+filename));
		}
	}

}


上面给出了servlet的处理过程,需要注意的是,使用request.getParts()方法必须给servlet添加注解@MultipartConfig,否则虽然不会抛出异常,但是获取不到数据。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值