1. 程式人生 > >使用httpclient模擬表單上傳檔案,後臺用struts2接收

使用httpclient模擬表單上傳檔案,後臺用struts2接收

本人是使用java,開發android後臺的,公司要求使用SSM框架,有一個功能要求是實現android大檔案的上傳。開發人員都是新手,以前沒有開發經驗,鼓搗了好久,也嘗試了兩個android框架,Xutils貌似跟struts2不太好整合,而AsyncHttpClient則遇到莫名奇妙的bug。後來本人查了很多資料,最後決定用httpclient模擬表單上傳。

下面直接上程式碼

客戶端部分:

public class HttpClientUpload{
	/**
	 *使用httpclient模擬form表單上傳檔案
	 * @param url 檔案上傳的目標地址
	 * @param filepath 要上傳的檔案路徑
	 * @param mapParams 文字引數(採用鍵值對應)
	 */
	public static void upload(String url, String filepath,HashMap<String, String> mapParams) {
		HttpClient client = new DefaultHttpClient();
		HttpPost httpPost = new HttpPost(url);
		client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION,HttpVersion.HTTP_1_1);
		client.getParams().setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, "utf-8");
		try {
			MultipartEntity entity = new MultipartEntity();//多個表單物件
			ContentBody fileBody = new FileBody(new File(filepath)); //表單檔案域
			entity.addPart("upload", fileBody);
		    entity.addPart("path", new StringBody(mapParams.get("savePath")));	// 字元引數部分
			httpPost.setEntity(entity);
			HttpResponse response = client.execute(httpPost);//執行post操作,並返回response
			String jsonData = EntityUtils.toString(response.getEntity(), "UTF-8");
			System.out.println(jsonData);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {
		String url ="http://localhost:8080/GoApp/uploadPro.action";
		String filepath="C:\\Users\\Administrator\\Desktop\\test.mkv";
		HashMap<String, String> mapParams = new HashMap<String, String>();
		mapParams.put("savePath", "\\gaopenghui");
		upload(url,filepath,mapParams);
	}
}
struts2的action配置:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
	<constant name="struts.i18n.encoding" value="utf-8" />
	<constant name="struts.multipart.maxSize" value="60000000" />
	<package name="struts2-message" extends="struts-default,json-default">
		<action name="uploadPro" class="com.eagle.message.action.UploadAction"
			method="upload">
			<!-- 預設的攔截器,必須要寫 -->
			<interceptor-ref name="fileUpload">
				<param name="maximumSize">42830000</param>
			</interceptor-ref>
			<interceptor-ref name="defaultStack" />
			<param name="savePath">/upload</param>
			<result type="json"></result>
		</action>
	</package>
</struts>

action的處理部分:
package com.eagle.message.action;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class UploadAction extends ActionSupport {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String path;
	private File upload;
	private String uploadContentType;
	private String uploadFileName;
	private String savePath;
	private HttpServletResponse response;

	public String getPath() {
		return path;
	}

	public void setPath(String path) {
		this.path = path;
	}

	@SuppressWarnings("deprecation")
	public String getSavePath() {
		return ServletActionContext.getRequest().getRealPath(savePath);
	}

	public void setSavePath(String savePath) {
		this.savePath = savePath;
	}

	public String getTitle() {
		return path;
	}

	public void setTitle(String title) {
		this.path = title;
	}

	public File getUpload() {
		return upload;
	}

	public void setUpload(File upload) {
		this.upload = upload;
	}

	public String getUploadContentType() {
		return uploadContentType;
	}

	public void setUploadContentType(String uploadContentType) {
		this.uploadContentType = uploadContentType;
	}

	public String getUploadFileName() {
		return uploadFileName;
	}

	public void setUploadFileName(String uploadFileName) {
		this.uploadFileName = uploadFileName;
	}

	/**
	 * 返回json資料的方法
	 * 
	 * @param json
	 *            要傳送的資料
	 */
	public void response(String json) {
		response = ServletActionContext.getResponse();
		response.setContentType("application/json;charset=utf-8");
		try {
			PrintWriter out = response.getWriter();
			out.print(json);
			out.flush();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 響應上傳檔案請求的action方法
	 */
	public void upload() {
		File file = new File(getSavePath() + path);
		if (!file.exists()) {// 若檔案目錄不存在,則建立目錄
			file.mkdirs();
		}
		try {
			FileOutputStream fos = new FileOutputStream(getSavePath() + path
					+ "\\" + uploadFileName);
			FileInputStream fis = new FileInputStream(getUpload());
			byte[] buffer = new byte[1024];
			int len = 0;
			while ((len = fis.read(buffer)) > 0) {
				fos.write(buffer, 0, len);
			}
			setUploadFileName(uploadFileName);
			fos.close();
			fis.close();
		} catch (Exception e) {
			response("檔案上傳失敗");
			e.printStackTrace();
			return;
		}
		response("檔案上傳成功");
	}
}

struts2預設使用Jakarta的Common-FileUpload檔案上傳框架,它可以將表單傳送來的資料進行封裝,如action中的upload對應表單中的upload域,而path對應表單中的path域,除此之外action中還有uploadContentType封裝了上傳檔案的檔案型別,uploadFileName封裝了上傳檔案的檔名(包括檔案型別在內,如test.jpg)。

這是本菜鳥的第一篇博文,希望對大家有所幫助。

httpclient要用到的jar包如圖所示: