最近一直被一個問題困擾,就是android上傳圖片到服務器,但是最終都沒能獲得圖片,不知道是什麼原因,先曬出後臺代碼(該代碼也是參考網上大多數網友的寫法)
主要用到兩個jar包,分別是commons-io 以及commons-fileupload,網上可以下載的到
package servlet;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class UploadHandleServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 得到上傳文件的保存目錄
String savePath = this.getServletContext().getRealPath(
"upload");
// 上傳時生成的臨時文件保存目錄
String tempPath = this.getServletContext().getRealPath("temp");
System.out.println(tempPath);
File tmpFile = new File(tempPath);
// 判斷上傳文件的保存目錄是否存在
if (!tmpFile.exists()) {
// 創建臨時目錄
tmpFile.mkdir();
}
// 消息提示
String message = "";
try {
// 使用Apache文件上傳組件處理文件上傳步驟:
// 1、創建一個DiskFileItemFactory工廠
DiskFileItemFactory factory = new DiskFileItemFactory();
// 設置上傳時生成的臨時文件的保存目錄
factory.setRepository(tmpFile);
// 2、創建一個文件上傳解析器
ServletFileUpload upload = new ServletFileUpload(factory);
//此處是爲了監聽上傳文件的進度,可有可無
upload.setProgressListener(new ProgressListener() {
public void update(long pBytesRead, long pContentLength,
int arg2) {
System.out.println("文件大小爲:" + pContentLength + ",當前已處理:"
+ pBytesRead);
}
});
// 解決上傳文件名的中文亂碼
upload.setHeaderEncoding("UTF-8");
// 3、判斷提交上來的數據是否是上傳表單的數據
if (!ServletFileUpload.isMultipartContent(request)) {
// 按照傳統方式獲取數據
return;
}
upload.setFileSizeMax(1024*1024);
upload.setSizeMax(1024*1024*10);
// 4、使用ServletFileUpload解析器解析上傳數據
List<FileItem> list = upload.parseRequest(request);
//此處出現的問題好多
for (FileItem item : list) {
// 如果fileitem中封裝的是普通輸入項的數據
if (item.isFormField()) {
String name = item.getFieldName();
// 解決普通輸入項的數據的中文亂碼問題
String value = item.getString("UTF-8");
// value = new String(value.getBytes("iso8859-1"),"UTF-8");
System.out.println(name + "=" + value);
} else {// 如果fileitem中封裝的是上傳文件
// 得到上傳的文件名稱,
String filename = item.getName();
System.out.println(filename);
if (filename == null || filename.trim().equals("")) {
continue;
}
// 注意:不同的瀏覽器提交的文件名是不一樣的,有些瀏覽器提交上來的文件名是帶有路徑的,如:
// c:\a\b\1.txt,而有些只是單純的文件名,如:1.txt
// 處理獲取到的上傳文件的文件名的路徑部分,只保留文件名部分
filename = filename
.substring(filename.lastIndexOf("\\") + 1);
// 獲取item中的上傳文件的輸入流
InputStream in = item.getInputStream();
// 創建一個文件輸出流
FileOutputStream out = new FileOutputStream(savePath + "\\"
+ filename);
byte buffer[] = new byte[1024];
// 判斷輸入流中的數據是否已經讀完的標識
int len = 0;
while ((len = in.read(buffer)) > 0) {
// 使用FileOutputStream輸出流將緩衝區的數據寫入到指定的目錄(savePath + "\\"
// + filename)當中
out.write(buffer, 0, len);
}
// 關閉輸入流
in.close();
// 關閉輸出流
out.close();
// 刪除處理文件上傳時生成的臨時文件
item.delete();
message = "文件上傳成功!";
}
}
} catch (FileUploadBase.FileSizeLimitExceededException e) {
e.printStackTrace();
request.setAttribute("message", "單個文件超出最大值!!!");
request.getRequestDispatcher("/pages/message.jsp").forward(request,
response);
return;
} catch (FileUploadBase.SizeLimitExceededException e) {
e.printStackTrace();
request.setAttribute("message", "上傳文件的總的大小超出限制的最大值!!!");
request.getRequestDispatcher("/message.jsp").forward(request,
response);
return;
} catch (Exception e) {
message = "文件上傳失敗!";
e.printStackTrace();
}
request.setAttribute("message", message);
request.getRequestDispatcher("/pages/message.jsp").forward(request,
response);
}
private String makePath(String filename,String savePath){
int hashcode = filename.hashCode();
int dir1 = hashcode&0xf; //0--15
int dir2 = (hashcode&0xf0)>>4; //0-15
//構造新的保存目錄
String dir = savePath + "\\" + dir1 + "\\" + dir2; //upload\2\3 upload\3\5
//File既可以代表文件也可以代表目錄
File file = new File(dir);
//如果目錄不存在
if(!file.exists()){
//創建目錄
file.mkdirs();
}
return dir;
}
private String makeFileName(String filename){ //2.jpg
return UUID.randomUUID().toString() + "_" + filename;
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
List<FileItem> list = upload.parseRequest(request) 爲什麼獲得list集合爲空,參考網上意見,是因爲Struts本身自帶過濾,如下:
修改前:
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
修改後:
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>UploadHandleServlet</servlet-name>
<servlet-class>servlet.UploadHandleServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UploadHandleServlet</servlet-name>
<url-pattern>/servlet/UploadHandleServlet</url-pattern>
</servlet-mapping>
爲什麼獲取不到圖片呢,忘記說了,android不是我寫的,所以沒有辦法曬出前端代碼,網上的android 前端好多這麼寫的:
- package com.example.photo;
- import java.io.BufferedReader;
- import java.io.DataOutputStream;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.io.OutputStream;
- import java.net.HttpURLConnection;
- import java.net.MalformedURLException;
- import java.net.URL;
- import java.util.UUID;
- public class HttpAssist {
- private static final String TAG = "uploadFile";
- private static final int TIME_OUT = 10 * 10000000; // 超時時間
- private static final String CHARSET = "utf-8"; // 設置編碼
- public static final String SUCCESS = "1";
- public static final String FAILURE = "0";
- public static String uploadFile(File file) {
- String BOUNDARY = UUID.randomUUID().toString(); // 邊界標識 隨機生成
- String PREFIX = "--", LINE_END = "\r\n";
- String CONTENT_TYPE = "multipart/form-data"; // 內容類型
- String RequestURL = "http://192.168.0.100:7080/YkyPhoneService/Uploadfile1";
- try {
- URL url = new URL(RequestURL);
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.setReadTimeout(TIME_OUT);
- conn.setConnectTimeout(TIME_OUT);
- conn.setDoInput(true); // 允許輸入流
- conn.setDoOutput(true); // 允許輸出流
- conn.setUseCaches(false); // 不允許使用緩存
- conn.setRequestMethod("POST"); // 請求方式
- conn.setRequestProperty("Charset", CHARSET); // 設置編碼
- conn.setRequestProperty("connection", "keep-alive");
- conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary="
- + BOUNDARY);
- if (file != null) {
- /**
- * 當文件不爲空,把文件包裝並且上傳
- */
- OutputStream outputSteam = conn.getOutputStream();
- DataOutputStream dos = new DataOutputStream(outputSteam);
- StringBuffer sb = new StringBuffer();
- sb.append(PREFIX);
- sb.append(BOUNDARY);
- sb.append(LINE_END);
- /**
- * 這裏重點注意: name裏面的值爲服務器端需要key 只有這個key 纔可以得到對應的文件
- * filename是文件的名字,包含後綴名的 比如:abc.png
- */
- sb.append("Content-Disposition: form-data; name=\"img\"; filename=\""
- + file.getName() + "\"" + LINE_END);
- sb.append("Content-Type: application/octet-stream; charset="
- + CHARSET + LINE_END);
- sb.append(LINE_END);
- dos.write(sb.toString().getBytes());
- InputStream is = new FileInputStream(file);
- byte[] bytes = new byte[1024];
- int len = 0;
- while ((len = is.read(bytes)) != -1) {
- dos.write(bytes, 0, len);
- }
- is.close();
- dos.write(LINE_END.getBytes());
- byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END)
- .getBytes();
- dos.write(end_data);
- dos.flush();
- /**
- * 獲取響應碼 200=成功 當響應成功,獲取響應的流
- */
- int res = conn.getResponseCode();
- if (res == 200) {
- return SUCCESS;
- }
- }
- } catch (MalformedURLException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return FAILURE;
- }
- }
+ file.getName() + "\"" + LINE_END);
sb.append("Content-Disposition: form-data; name=\"file\"; filename=\""
+ file.getName() + "\"" + LINE_END);
這兩者有什麼區別,有大神知道的說一下 啊