1. 程式人生 > >JavaEE——爬蟲(重寫request)

JavaEE——爬蟲(重寫request)

 重寫request,讓呼叫request的時候,實則是呼叫該類中的Map集合

import java.io.File;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import edu.edu.article.Attachment;

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{
				//建立上傳所需要的兩個物件
                // 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;
	}
}