HttpClient實(shí)現(xiàn)文件上傳功能
除了文件下載外,文件上傳也是項(xiàng)目開發(fā)中經(jīng)常用到的功能。此時(shí)需要用HttpClient類庫(kù)的擴(kuò)展包HttpMime中的MultipartEntity類,此類同樣實(shí)現(xiàn)了HttpEntity接口。需要注意的是HttpClient通過(guò)POST來(lái)上傳文件,而不是通過(guò)流的形式。
示例:使用HttpClient實(shí)現(xiàn)文件上傳功能。
第一步:要求在服務(wù)器端使用fileupload組件接收客戶端提交內(nèi)容。新建一個(gè)JSP項(xiàng)目zghc,首先在WEB-INF/lib目錄下加入commons-fileupload-1.2.2.jar和commons-io-2.4.jar兩個(gè)jar包,然后再提供一個(gè)對(duì)用戶提交數(shù)據(jù)(文本、文件)進(jìn)行處理的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 { ?? ??? ?// 檢測(cè)是不是文件上傳的請(qǐng)求 ?? ??? ?boolean isMultipart = ServletFileUpload.isMultipartContent(request); ?? ??? ?if (isMultipart) {// 屬于上傳文件的請(qǐng)求 ?? ??? ??? ?// 創(chuàng)建磁盤工廠,該類用來(lái)配置上傳組件ServletFileUpload ?? ??? ??? ?DiskFileItemFactory factory = new DiskFileItemFactory(); ?? ??? ??? ?factory.setSizeThreshold(10 * 1024 * 1024); ?? ??? ??? ?factory.setRepository(new File("D:/")); // 設(shè)置存放臨時(shí)文件的目錄 ?? ??? ??? ?// 使用磁盤工廠實(shí)例化上傳組件 ?? ??? ??? ?ServletFileUpload upload = new ServletFileUpload(factory); ?? ??? ??? ?upload.setSizeMax(10 * 1024 * 1024); // 設(shè)置允許的最大上傳尺寸 ?? ??? ??? ?upload.setHeaderEncoding("UTF-8");// 明確指定使用UTF-8編碼 ?? ??? ??? ?PrintWriter out = response.getWriter(); ?? ??? ??? ?try {?? ?// 獲取客戶端提交過(guò)來(lái)的所有請(qǐng)求參數(shù) ?? ??? ??? ??? ?List<FileItem> items = upload.parseRequest(request); // 解析 ?? ??? ??? ??? ?for (FileItem item : items) {//對(duì)用戶上傳的所有文件進(jìn)行遍歷 ?? ??? ??? ??? ??? ?if (item.isFormField()) {// 如果是表單字段 ?? ??? ??? ??? ??? ??? ?System.out.println(item.getFieldName()+" ?"+ item.getString("UTF-8")); ?? ??? ??? ??? ??? ?} else {// 如果是文件 ?? ??? ??? ??? ??? ??? ?String path = request.getSession().getServletContext() ?? ??? ??? ??? ??? ??? ??? ??? ?.getRealPath("/");// 站點(diǎn)根目錄的路徑 ?? ??? ??? ??? ??? ??? ?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("文件超過(guò)規(guī)定大小"); ?? ??? ??? ?} ?? ??? ?} ?? ?} }
FileItemFactory類的setSizeThreshold()方法用來(lái)設(shè)置上傳文件時(shí)用于臨時(shí)存放文件的內(nèi)存的大小,超出的部分將臨時(shí)存放在硬盤,可以使用FileItemFactory類的 setRepository()方法設(shè)置臨時(shí)文件的目錄。
在調(diào)用item.write()方法寫入數(shù)據(jù)到文件中時(shí),如果文件的名稱是中文,有可能會(huì)出現(xiàn)亂碼;另外需要注意的是Windows系統(tǒng)中item.getName()方法的返回的值是帶路徑的。
提示:
如果使用tomcat6,采用傳統(tǒng)的在web.xml方式中配置Servlet,編號(hào)②處的代碼需要改為:item.getName().lastIndexOf("\")
第二步:提供一個(gè)JSP文件upload.jsp,對(duì)上面的Servlet進(jìn)行測(cè)試。注意在此JSP文件中需要設(shè)置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"> ?? ??? ??? ?標(biāo)題:<input type="text" name="name"/> ?? ??? ??? ?文件:<input type="file" name="imgFile"/> ?? ??? ??? ?<input type="submit" value="提交"/> ?? ??? ?</form> ?? ?</body> </html>
為了能上傳文件,必須將表單的method屬性設(shè)置為POST、enctype屬性設(shè)置為multipart/form-data,只有這樣,瀏覽器才會(huì)把用戶選擇文件的二進(jìn)制數(shù)據(jù)發(fā)送給服務(wù)器。
第四步:將上面的JSP項(xiàng)目部署到tomcat中,然后在打開的upload.jsp頁(yè)面中輸入文件名,選中要上傳的文件,單擊【提交】按鈕,然后在tomcat下的webapps\zghc目錄下確實(shí)發(fā)現(xiàn)上傳的文件,表明文件上傳成功。
第五步:新建一個(gè)Android項(xiàng)目,將httpmime_XXXX.jar文件添加到當(dāng)前項(xiàng)目的classpath路徑下面,然后在項(xiàng)目中添加一個(gè)實(shí)現(xiàn)上傳功能的工具類,具體代碼如下所示:
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);// 創(chuàng)建HttpPost對(duì)象 ?? ??? ?// 如果傳遞參數(shù)個(gè)數(shù)比較多的話可以對(duì)傳遞的參數(shù)進(jìn)行封裝 ?? ??? ?MultipartEntity entity = new MultipartEntity(); ?? ??? ?try { ?? ??? ??? ?for (String key : map.keySet()) {?? ?// 封裝請(qǐng)求參數(shù) StringBody value = new StringBody(map ?? ??? ??? ??? ??? ??? ?.get(key), Charset.forName("UTF-8"));//避免傳遞漢字出現(xiàn)亂碼 ?? ??? ??? ??? ?entity.addPart(new FormBodyPart(key,value)); ?? ??? ??? ?} ?? ??? ??? ?if(file != null) ?? ??? ??? ??? ?entity.addPart("myfile", new FileBody(file)); ?? ??? ??? ?post.setEntity(entity);// 設(shè)置請(qǐng)求參數(shù) ?? ??? ??? ?synchronized (httpClient) { ?? ??? ??? ??? ?HttpResponse response = httpClient.execute(post);// 發(fā)送POST請(qǐng)求 ?? ??? ??? ??? ?if (response.getStatusLine().getStatusCode() == 200){ ?? ??? ??? ??? ??? ?HttpEntity resEntity = response.getEntity(); ?? ??? ??? ??? ??? ?result = EntityUtils.toString(resEntity, "UTF-8"); ?? ??? ??? ??? ?} ?? ??? ??? ?} ?? ??? ?} catch (IOException e) { ?? ??? ??? ?e.printStackTrace(); ?? ??? ?} ?? ??? ?return result; ?? ?} }
第六步:為了提高用戶體驗(yàn),我們提供一個(gè)線程類來(lái)實(shí)現(xiàn)文件文件上傳的功能,具體代碼如下所示:
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); ?? ??? ?} ?? ?} }
第七步:在主布局文件中提供一個(gè)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, "提交數(shù)據(jù)成功", 1).show(); ?? ??? ??? ?} else { ?? ??? ??? ??? ?Toast.makeText(MainActivity.this, "提交數(shù)據(jù)失敗", 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(); ?? ?} }
在保證第一步創(chuàng)建的JSP項(xiàng)目已經(jīng)部署到tomcat中且tomcat已經(jīng)啟動(dòng)的前提下,運(yùn)行本程序,發(fā)現(xiàn)當(dāng)點(diǎn)擊客戶端主界面中的Button按鈕后,在tomcat下的webapps/zghc目錄下確實(shí)看到了剛才上傳的文件。
大家可以將前面章節(jié)中學(xué)到Android中制作文件管理器的知識(shí)和本示例程序結(jié)合起來(lái),實(shí)現(xiàn)一個(gè)能夠通過(guò)圖形化方式選擇文件的文件上傳軟件。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java FtpClient 實(shí)現(xiàn)文件上傳服務(wù)
本文主要對(duì)Java FtpClient實(shí)現(xiàn)簡(jiǎn)單的圖片上傳到服務(wù)器的方法進(jìn)行介紹,并且展示的小demo中,對(duì)配置過(guò)程中主要碰到的問(wèn)題:關(guān)于文件權(quán)限的問(wèn)題也進(jìn)行了說(shuō)明,下面跟著小編一起來(lái)看下吧2016-12-12開源項(xiàng)目ERM模型轉(zhuǎn)jpa實(shí)體maven插件使用
這篇文章主要為大家介紹了開源項(xiàng)目ERM模型轉(zhuǎn)jpa實(shí)體maven插件的使用說(shuō)明,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-03-03Java實(shí)戰(zhàn)之醫(yī)院管理系統(tǒng)的實(shí)現(xiàn)
這篇文章主要介紹了如何利用Java實(shí)現(xiàn)醫(yī)院管理系統(tǒng),文中用到的技術(shù)有:SpringBoot、Layui、Freemaker等,感興趣的同學(xué)可以了解一下2022-04-04SpringBoot項(xiàng)目?jī)?yōu)雅的全局異常處理方式(全網(wǎng)最新)
這篇文章主要介紹了SpringBoot項(xiàng)目?jī)?yōu)雅的全局異常處理方式(全網(wǎng)最新),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04springMvc注解之@ResponseBody和@RequestBody詳解
本篇文章主要介紹了springMvc注解之@ResponseBody和@RequestBody詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-05-05