1. 程式人生 > >jsp頁面中添加 enctype="multipart-formdata'無法提交到後臺得解決思路

jsp頁面中添加 enctype="multipart-formdata'無法提交到後臺得解決思路

this map() for void tom int ctype nds ride

解決產品添加頁面中有提交文件的解決思路

設計原則

在jsp頁面的表單裏面

<form action="ArticleServlet" enctype="multipart/form-data" method="post">
<input type="hidden" name="method" value="add">

<div>

<input type="text" name="title" id="title" value="" size="60" maxlength="200" />

</div>

後臺xxxServlet中

無法通過這種方式進行後臺表單數據的接收

String name = request.getparameter(title);

為什麽呢?

因為在xxxServlet中 doPost() doGet()方法中沒法接收到method方法!!

解決思路見圖

技術分享圖片

使用裝飾流設計模式包裝httpServletRequest

定義這樣一個類

class MultipartrequestWrapper extends HttpRequestWrapper {

  public MultipartRequestWrapper(HttpServletRequest request) {

  super(request);

//首先判斷是否multipart編碼類型
//如果是multipart編碼類型,就逐個從request中取出各個表單域
//contentType:multipart/form-data; boundary=---------------------------317894718690
//如果表單域是普通的表單域,則將它的值取出,放到allParams中(通過表單上傳到服務器是通過requestUtil.copyParam())
//如果表單域是文件,則
//1、把文件先存儲到磁盤的某個目錄中!
//2、把文件的有關信息(名稱,類型,上傳時間)包裝成Attachment[]類型
//3、把包裝好的Attachment[]類型,放到allParams中
//拿到叠代器

  

try {
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if(!isMultipart){
allParams = request.getParameterMap();
}else{

// Create a new file upload handler
allParams = new HashMap();
ServletFileUpload upload = new ServletFileUpload();
FileItemIterator iter = upload.getItemIterator(request);
while(iter.hasNext()){
FileItemStream item = iter.next();//拿到表單域對象
String name = item.getFieldName();//拿到表單域的名稱
//得到表單域得值(這是一個輸入流)
InputStream stream = item.openStream();
//如果是普通表單域
if(item.isFormField()){
String value = Streams.asString(stream,request.getCharacterEncoding());
//此處不能直接allParams.put(name,value);如果在表單處有兩個相同字段都需要保存下來,如若不保存後面會覆蓋前面的
addFieldsAndValuesToMap(name, value);
}else{
//文件附件類型
if(stream.available()!=0){
//如果是ie瀏覽器上傳就會把路徑也提交上來
//而我們只需要文件名
String filename = item.getName();
if(filename!=null){
//為了解決IE上傳本地文件路徑問題
filename = FilenameUtils.getName(filename);//只需要文件名不需要路徑
}
//3是否自動關閉
Streams.copy(stream,new FileOutputStream("D:/temp/update/"+filename), true);
Attachment attachment = new Attachment();
attachment.setContentType(item.getContentType());
attachment.setName(filename);
attachment.setUploadTime(new Date());
//如果是多個文件
addFieldsAndValuesToMap(name, attachment);
}
}


}
}
}catch (Exception e) {
e.printStackTrace();
}

}

//為了處理多個上傳文件
private void addFieldsAndValuesToMap(String name, Attachment value) {
Attachment[] fieldValues = (Attachment[]) allParams.get(name);
if(fieldValues==null){
allParams.put(name, new Attachment[]{value});
}else{
//如果不為空說明map集合裏面已經有一份了
//‘sex‘,‘male‘界面又傳來一個表單仍然需要保存
//‘sex‘,‘male‘,null
fieldValues = Arrays.copyOf(fieldValues, fieldValues.length+1);
//再給新數組賦值
fieldValues[fieldValues.length-1]=value;//給最後一個賦值最新的value
allParams.put(name, fieldValues);//
}

}

/**
* 目標實現數組的拷貝
* @param name
* @param value
* map的鍵是唯一的
*/
private void addFieldsAndValuesToMap(String name, String value) {
String[] fieldValues = (String[]) allParams.get(name);
if(fieldValues==null){
allParams.put(name, new String[]{value});
}else{
//如果不為空說明map集合裏面已經有一份了
//‘sex‘,‘male‘界面又傳來一個表單仍然需要保存
//‘sex‘,‘male‘,null
fieldValues = Arrays.copyOf(fieldValues, fieldValues.length+1);
//再給新數組賦值
fieldValues[fieldValues.length-1]=value;//給最後一個賦值最新的value
allParams.put(name, fieldValues);//{‘sex‘,‘male‘,‘male‘}
}

}

@Override
public String getParameter(String name) {
  String[] values = (String[]) allParams.get(name);
  if(values != null){
    return values[0];
}
  return null;
}

@Override
public Map getParameterMap() {

return allParams;
}


public Map getAllParams() {
  return allParams;
}

public void setAllParams(Map allParams) {
  this.allParams = allParams;
}
}

}

如此在xxxServlet中

Attachment[] attachments = (Attachment[])request.getParameterMap().get("attachs");
if(attachments != null){
for(Attachment atta : attachments){
System.out.println(atta.getName()+",已經被上傳,文件類型是:"+atta.getContentType());
  a.addAttachments(atta);// GRASP模式中專家模式的運用
}
}

在baseServlet中悄悄得把httpServletRequest替換成MultipartServletRequest

這樣在客戶端的servlet就依賴於MultipartServletRequest request

@Override
public String getParameter(String name) {
  String[] values = (String[]) allParams.get(name);
  if(values != null){
    return values[0];
}
  return null;
}

@Override
public Map getParameterMap() {

return allParams;
}

jsp頁面中添加 enctype="multipart-formdata'無法提交到後臺得解決思路