重写request,使其可以读取文件

本文介绍了一种自定义的Servlet请求处理方式,通过继承HttpServletRequestWrapper实现对HTTP请求中的文件进行解析并保存的功能。该方法能够同时处理普通表单字段和文件上传字段。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 Servlet里面的request只能读取字符串,现在重写,使其也可以读取文件

public class MyHttpServletRequest extends HttpServletRequestWrapper {
	//先创建一个新的集合,这个集合我们要在其中添加普通表单字段和文件类型的表单字段
	private Map allParams = null;
	public MyHttpServletRequest(HttpServletRequest request) {
		super(request);
		
		try {
			//先判断request是不是multipart这种类型
			if(!ServletFileUpload.isMultipartContent(request)){
				allParams = request.getParameterMap();//如果不是multipart类型,那么我们直接把request中原来的参数集合的引用交给allParams
			}else{
				allParams = new HashMap();
				//创建上传所需要的两个对象
                // FileItemFactory 这个类用来组织所有文件,通过统一的接口访问文件的信息。
			    DiskFileItemFactory factory = new DiskFileItemFactory();
			    ServletFileUpload sfu = new ServletFileUpload(factory); //解析器依赖于工厂
			    //从request的流中解析出表单每个属性的名:值对(FileItem),注意,这个值可能是字符串,也可能是文件
			    List<FileItem> items = sfu.parseRequest(request);
			    for(FileItem item : items){
			    	String name = item.getFieldName();//表单的name属性的名字
			    	InputStream valueStream = item.getInputStream();//这个是值对象,因为值可以是字符串也可以是文件,所以我们用字节流的方式得到数据
			    	//isFormField()方法是判断当前表单项是不是字符串类型的值
			    	if(item.isFormField()){
			    		//当我们的字段是普通字段时
			    		String value = item.getString("utf-8");//取到表单项中的字符串值
			    		addFieldToMap(name,value);// 把普通字段的名值对放入我们自己的集合中
			    	}else{
			    		String fileName = item.getName();//取文件名,是个客户端的全路径  c:/桌面/单页背面.jpg
			    		String contentType = item.getContentType();//取http请求中该文件的mime类型
			    		//把上传的文件的字节流保存到文件当中
			    		//解决的问题1:创建一个上传文件的目录的绝对路径
			    		//     第一步:先取到我们web项目的根路径,对我们的项目来说,就是:E:\apache-tomcat-8.0.14\webapps\cms\
			    		String rootpath = request.getSession().getServletContext().getRealPath("/");
			    		//     第二步:创建上传文件的目录的绝对路径
			    		String uploadpath = rootpath + "/upload/";
			    		File dir = new File(uploadpath);
			    		//判断一下这个路径是否存在
			    		if(!dir.exists()){
			    			dir.mkdir();//如果不存在则创建这个目录
			    		}
			    		//根据文件名和上传目录,创建一个文件对象
			    		String[] nstemp = fileName.split("\\/|\\\\");  //   \/|\\
			    		String filename = nstemp[nstemp.length - 1]; // 单页背面.jpg
			    		
			    		File file = new File(uploadpath,fileName);//根据目录名和文件名得到完整文件对象
			    		
			    		item.write(file);
			    		
			    		//allParams集合中怎么保存文件这样的数据?
			    		//把附件信息保存在Attachment对象当中
			    		Attachment a = new Attachment();
			    		a.setContenttype(contentType);
			    		a.setFilename(filename);
			    		
			    		addAttachmentToMap(name,a);//把附件对象添加到allparams集合中的方法
			    	}
			    }
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	//把附件对象添加到allparams集合中的方法
	private void addAttachmentToMap(String name, Attachment a) {
		Attachment[] as = (Attachment[])allParams.get(name);
		if(as != null){
			as = Arrays.copyOf(as, as.length + 1);
			as[as.length - 1] = a;
		}else{
			as = new Attachment[]{a};
		}
		allParams.put(name, as);
	}
	/**
	 * 把普通字段的名值对放入我们自己的集合中
	 * @param name
	 * @param value
	 */
	private void addFieldToMap(String name, String value) {
		String[] param = (String[])allParams.get(name);
		if(param != null){
			param = Arrays.copyOf(param, param.length + 1);
			param[param.length - 1] = value;
		}else{
			param = new String[]{value};
		}
		allParams.put(name, param);
	}

	@Override
	public String getParameter(String name) {
		
		return getParameterValues(name)[0];
	}

	@Override
	public Map getParameterMap() {
		return allParams;
	}

	@Override
	public String[] getParameterValues(String name) {
		return (String[])allParams.get(name);
	}
	
}
public class Attachment {
	
	private String filename;
	private String contenttype;
	public String getFilename() {
		return filename;
	}
	public void setFilename(String filename) {
		this.filename = filename;
	}
	public String getContenttype() {
		return contenttype;
	}
	public void setContenttype(String contenttype) {
		this.contenttype = contenttype;
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值