HttpClient實現文件上傳功能
除瞭文件下載外,文件上傳也是項目開發中經常用到的功能。此時需要用HttpClient類庫的擴展包HttpMime中的MultipartEntity類,此類同樣實現瞭HttpEntity接口。需要註意的是HttpClient通過POST來上傳文件,而不是通過流的形式。
示例:使用HttpClient實現文件上傳功能。
第一步:要求在服務器端使用fileupload組件接收客戶端提交內容。新建一個JSP項目zghc,首先在WEB-INF/lib目錄下加入commons-fileupload-1.2.2.jar和commons-io-2.4.jar兩個jar包,然後再提供一個對用戶提交數據(文本、文件)進行處理的Servlet,具體代碼如下所示:
@WebServlet("/uploadServlet") public class UploadServlet extends HttpServlet { // 使用fileupload組件 private static final long serialVersionUID = 1L; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 檢測是不是文件上傳的請求 boolean isMultipart = ServletFileUpload.isMultipartContent(request); if (isMultipart) {// 屬於上傳文件的請求 // 創建磁盤工廠,該類用來配置上傳組件ServletFileUpload DiskFileItemFactory factory = new DiskFileItemFactory(); factory.setSizeThreshold(10 * 1024 * 1024); factory.setRepository(new File("D:/")); // 設置存放臨時文件的目錄 // 使用磁盤工廠實例化上傳組件 ServletFileUpload upload = new ServletFileUpload(factory); upload.setSizeMax(10 * 1024 * 1024); // 設置允許的最大上傳尺寸 upload.setHeaderEncoding("UTF-8");// 明確指定使用UTF-8編碼 PrintWriter out = response.getWriter(); try { // 獲取客戶端提交過來的所有請求參數 List<FileItem> items = upload.parseRequest(request); // 解析 for (FileItem item : items) {//對用戶上傳的所有文件進行遍歷 if (item.isFormField()) {// 如果是表單字段 System.out.println(item.getFieldName()+" "+ item.getString("UTF-8")); } else {// 如果是文件 String path = request.getSession().getServletContext() .getRealPath("/");// 站點根目錄的路徑 String name = item.getName().substring( item.getName().lastIndexOf("/") + 1); // ---② // 保存用戶上傳的文件到指定目錄 item.write(new File(path, name)); System.out.println("上傳完畢"); response.setCharacterEncoding("UTF-8"); out.println("上傳完畢"); } } } catch (Exception e) { e.printStackTrace(); out.println("文件超過規定大小"); } } } }
FileItemFactory類的setSizeThreshold()方法用來設置上傳文件時用於臨時存放文件的內存的大小,超出的部分將臨時存放在硬盤,可以使用FileItemFactory類的 setRepository()方法設置臨時文件的目錄。
在調用item.write()方法寫入數據到文件中時,如果文件的名稱是中文,有可能會出現亂碼;另外需要註意的是Windows系統中item.getName()方法的返回的值是帶路徑的。
提示:
如果使用tomcat6,采用傳統的在web.xml方式中配置Servlet,編號②處的代碼需要改為:item.getName().lastIndexOf("\")
第二步:提供一個JSP文件upload.jsp,對上面的Servlet進行測試。註意在此JSP文件中需要設置form表單的enctype的值為multipart/form-data。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>My JSP 'index.jsp' starting page</title> </head> <body> <form action="uploadServlet" method="post" enctype="multipart/form-data"> 標題:<input type="text" name="name"/> 文件:<input type="file" name="imgFile"/> <input type="submit" value="提交"/> </form> </body> </html>
為瞭能上傳文件,必須將表單的method屬性設置為POST、enctype屬性設置為multipart/form-data,隻有這樣,瀏覽器才會把用戶選擇文件的二進制數據發送給服務器。
第四步:將上面的JSP項目部署到tomcat中,然後在打開的upload.jsp頁面中輸入文件名,選中要上傳的文件,單擊【提交】按鈕,然後在tomcat下的webapps\zghc目錄下確實發現上傳的文件,表明文件上傳成功。
第五步:新建一個Android項目,將httpmime_XXXX.jar文件添加到當前項目的classpath路徑下面,然後在項目中添加一個實現上傳功能的工具類,具體代碼如下所示:
public class HttpClientUtil { public static HttpClient httpClient = new DefaultHttpClient(); public static String sendPost(String url,HashMap<String,String> map,File file){ String result = null; HttpPost post = new HttpPost(url);// 創建HttpPost對象 // 如果傳遞參數個數比較多的話可以對傳遞的參數進行封裝 MultipartEntity entity = new MultipartEntity(); try { for (String key : map.keySet()) { // 封裝請求參數 StringBody value = new StringBody(map .get(key), Charset.forName("UTF-8"));//避免傳遞漢字出現亂碼 entity.addPart(new FormBodyPart(key,value)); } if(file != null) entity.addPart("myfile", new FileBody(file)); post.setEntity(entity);// 設置請求參數 synchronized (httpClient) { HttpResponse response = httpClient.execute(post);// 發送POST請求 if (response.getStatusLine().getStatusCode() == 200){ HttpEntity resEntity = response.getEntity(); result = EntityUtils.toString(resEntity, "UTF-8"); } } } catch (IOException e) { e.printStackTrace(); } return result; } }
第六步:為瞭提高用戶體驗,我們提供一個線程類來實現文件文件上傳的功能,具體代碼如下所示:
public class UploadThread extends Thread { private String url; private HashMap<String, String> map; private File file; private Handler handler; public UploadThread(String url, HashMap<String, String> map, File file, Handler handler) { this.url = url; this.map = map; this.file = file; this.handler = handler; } @Override public void run() { String result = HttpClientUtil.sendPost(url, map, file); //具體上傳代碼 System.out.println("aaaaa" + result); if ("上傳完畢".equals(result.trim())) { handler.sendEmptyMessage(1); } else { handler.sendEmptyMessage(0); } } }
第七步:在主佈局文件中提供一個onClick屬性值為upload的Button,然後修改MainAcvitity類的代碼如下所示:
public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } private Handler handler = new Handler() { public void handleMessage(Message msg) { if (msg.what == 1) { Toast.makeText(MainActivity.this, "提交數據成功", 1).show(); } else { Toast.makeText(MainActivity.this, "提交數據失敗", 1).show(); } } }; public void upload(View view) { HashMap<String, String> map = new HashMap<String, String>(); map.put("username", "music"); File sdPath = Environment.getExternalStorageDirectory(); File file = new File(sdPath + "/zbjbxf.mp3"); String url = "http://10.0.2.2:8080/zghc/uploadServlet"; UploadThread thread = new UploadThread(url, map, file, handler); thread.start(); } }
在保證第一步創建的JSP項目已經部署到tomcat中且tomcat已經啟動的前提下,運行本程序,發現當點擊客戶端主界面中的Button按鈕後,在tomcat下的webapps/zghc目錄下確實看到瞭剛才上傳的文件。
大傢可以將前面章節中學到Android中制作文件管理器的知識和本示例程序結合起來,實現一個能夠通過圖形化方式選擇文件的文件上傳軟件。
以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。
推薦閱讀:
- HttpClient實現表單提交上傳文件
- Spring遠程調用HttpClient/RestTemplate的方法
- java 利用HttpClient PostMethod提交json數據操作
- JavaWeb實現文件上傳功能詳解
- C#中HttpClient使用註意(預熱與長連接)