首頁 > 軟體

HttpClient實現檔案上傳功能

2022-08-14 14:02:05

除了檔案下載外,檔案上傳也是專案開發中經常用到的功能。此時需要用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下的webappszghc目錄下確實發現上傳的檔案,表明檔案上傳成功。

第五步:新建一個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中製作檔案管理器的知識和本範例程式結合起來,實現一個能夠通過圖形化方式選擇檔案的檔案上傳軟體。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com