HttpClient實(shí)現(xiàn)文件上傳功能
除了文件下載外,文件上傳也是項(xiàng)目開發(fā)中經(jīng)常用到的功能。此時(shí)需要用HttpClient類庫的擴(kuò)展包HttpMime中的MultipartEntity類,此類同樣實(shí)現(xiàn)了HttpEntity接口。需要注意的是HttpClient通過POST來上傳文件,而不是通過流的形式。
示例:使用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 {
?? ??? ?// 檢測是不是文件上傳的請求
?? ??? ?boolean isMultipart = ServletFileUpload.isMultipartContent(request);
?? ??? ?if (isMultipart) {// 屬于上傳文件的請求
?? ??? ??? ?// 創(chuàng)建磁盤工廠,該類用來配置上傳組件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 {?? ?// 獲取客戶端提交過來的所有請求參數(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ī)定大小");
?? ??? ??? ?}
?? ??? ?}
?? ?}
}FileItemFactory類的setSizeThreshold()方法用來設(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)行測試。注意在此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頁面中輸入文件名,選中要上傳的文件,單擊【提交】按鈕,然后在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()) {?? ?// 封裝請求參數(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è)置請求參數(shù)
?? ??? ??? ?synchronized (httpClient) {
?? ??? ??? ??? ?HttpResponse response = httpClient.execute(post);// 發(fā)送POST請求
?? ??? ??? ??? ?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è)線程類來實(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é)合起來,實(shí)現(xiàn)一個(gè)能夠通過圖形化方式選擇文件的文件上傳軟件。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java 遞歸查詢部門樹形結(jié)構(gòu)數(shù)據(jù)的實(shí)踐
本文主要介紹了Java 遞歸查詢部門樹形結(jié)構(gòu)數(shù)據(jù)的實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
intellij idea14打包apk文件和查看sha1值
這篇文章主要為大家詳細(xì)介紹了intellij idea14打包apk文件和查看sha1值,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-10-10
mybatis plus表的創(chuàng)建時(shí)間和修改時(shí)間的操作方法
這篇文章主要介紹了mybatis plus表的創(chuàng)建時(shí)間和修改時(shí)間的實(shí)現(xiàn)方法,本文給大家分享兩種方法,每種方法通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2021-09-09
將Java項(xiàng)目打包成可執(zhí)行的jar包
這篇文章主要介紹了將Java項(xiàng)目打包成可執(zhí)行的jar包,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
Spring占位符Placeholder的實(shí)現(xiàn)原理解析
這篇文章主要介紹了Spring占位符Placeholder的實(shí)現(xiàn)原理,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03
使用SpringBoot整合ssm項(xiàng)目的實(shí)例詳解
Spring Boot 現(xiàn)在已經(jīng)成為 Java 開發(fā)領(lǐng)域的一顆璀璨明珠,它本身是包容萬象的,可以跟各種技術(shù)集成。這篇文章主要介紹了使用SpringBoot整合ssm項(xiàng)目,需要的朋友可以參考下2018-11-11
Java實(shí)現(xiàn)List轉(zhuǎn)換為Map的方法小結(jié)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)List轉(zhuǎn)換為Map的一些常見的方法,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以參考一下2024-03-03

