通過httpclient發送請求的幾種方式,發送文件、參數、json對象

原文鏈接:https://blog.csdn.net/akxj2022/article/details/88691698

使用工具:idea

框架:gradle、springboot

實現目標:使用 httpclient 發送文件/參數/json對象

method:post

主要用到的jar包:

    compile group: 'net.sf.json-lib', name: 'json-lib', version: '2.4', classifier: 'jdk15'
 
    //httpclient
    // https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient
    compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.3'
    // https://mvnrepository.com/artifact/org.apache.httpcomponents/httpmime
    compile group: 'org.apache.httpcomponents', name: 'httpmime', version: '4.5.3'
    // https://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore
    compile group: 'org.apache.httpcomponents', name: 'httpcore', version: '4.4.6'

花了大半天終於寫完這個測試類,能正常跑起來,下面主要貼出來兩種 httpclient 的發送和接收,基本夠用

特別注意:

1.文件和json對象是不能一起發送的,要發也是把json對象toString一下,見第一個方法
2.發送json對象,並用Requestbody接收,這種智能發對象,不能發文件,見第二個方法

預備幾個方法,因爲模擬數據用到的一樣,所以先貼這幾個公用方法:

 
    //模擬文件數據,這裏自己改成自己的文件就可以了
    private static List<Map<String, Object>> getFileList() {
        //文件列表,搞了三個本地文件
        List<Map<String, Object>> fileList = new ArrayList<>();
        Map<String, Object> filedetail1 = new HashMap<>();
        filedetail1.put("location", "F:\\me\\photos\\動漫\\3ba39425fec1965f4d088d2f.bmp");
        filedetail1.put("fileName", "圖片1");
        fileList.add(filedetail1);
        Map<String, Object> filedetail2 = new HashMap<>();
        filedetail2.put("location", "F:\\me\\photos\\動漫\\09b3970fd3f5cc65b1351da4.bmp");
        filedetail2.put("fileName", "圖片2");
        fileList.add(filedetail2);
        Map<String, Object> filedetail3 = new HashMap<>();
        filedetail3.put("location", "F:\\me\\photos\\動漫\\89ff57d93cd1b72cd0164ec9.bmp");
        filedetail3.put("fileName", "圖片3");
        fileList.add(filedetail3);
        return fileList;
    }
 
    //模擬json對象數據
    private static JSONObject getJsonObj() {
        /**
         * 這裏搞json對象方法很多
         * 1.直接字符串貼過來,然後解析成json
         * 2.用map<String,Object>,做好數據之後解析成json,.toJSONString
         * 3.new 一個JSONObject對象,然後自己拼接
         * 下面的例子用map好了,這個應該通俗易懂
         */
        Map<String, Object> main = new HashMap<>();
        main.put("token", "httpclient with file stringParam jsonParam and jasonArrayParam");
        List<Map<String, Object>> contentList = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            Map<String, Object> content = new HashMap<>();
            content.put("id", i);
            content.put("name", "數據" + i);
            contentList.add(content);
        }
        main.put("content", contentList);
        JSONObject jsonObject = JSONObject.fromObject(main);
        System.out.println("jsonObject:" + jsonObject);
//        //json字符串,去網上格式化一下,直接貼過來,然後解析成json
//        String jsonString = "{\n" +
//                "    \"token\": \"stream data\", \n" +
//                "    \"content\": [\n" +
//                "        {\n" +
//                "            \"id\": \"1\", \n" +
//                "            \"name\": \"3ba39425fec1965f4d088d2f.bmp\"\n" +
//                "        }, \n" +
//                "        {\n" +
//                "            \"id\": \"2\", \n" +
//                "            \"name\": \"09b3970fd3f5cc65b1351da4.bmp\"\n" +
//                "        }, \n" +
//                "        {\n" +
//                "            \"id\": \"3\", \n" +
//                "            \"name\": \"89ff57d93cd1b72cd0164ec9.bmp\"\n" +
//                "        }\n" +
//                "    ]\n" +
//                "}";
//        JSONObject jsonObject = JSONObject.parseObject(jsonString);
        return jsonObject;
    }
 
    //模擬json數組數據
    private static JSONArray getJsonArray() {
        List<Map<String, Object>> contentList = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            Map<String, Object> content = new HashMap<>();
            content.put("id", i);
            content.put("name", "array數據" + i);
            contentList.add(content);
        }
        JSONArray jsonArray =JSONArray.fromObject(contentList);
        System.out.println("jsonArray:" + jsonArray);
        return jsonArray;
    }

主函數:

   /**
     * 主函數
     * @param args
     * @throws Exception
     */
    public static void main(String args[]) throws Exception {
        //模擬流文件及參數上傳
//        testStreamUpload();
        //httpClient模擬文件上傳
        testFileParamUpload();
        //httpClient模擬發送json對象,用JSONObject接收
        testJSONObjectUpload();
    }
 
    /**
     * httpClient模擬文件上傳
     */
    static void testFileParamUpload() {
        String url = "http://127.0.0.1:8090/kty/test/receiveHttpClientWithFile";
        //json字符串,模擬了一個,傳圖片名字吧
        Map<String, Object> param = new HashMap<>();
        param.put("paramString", "i'm paramString!");
        param.put("paramJSONObject", getJsonObj().toString());
        param.put("paramJSONArray", getJsonArray().toString());
 
 
        doPostFileAndParam(url, getFileList(), param);
    }
 
    /**
     * 測試發送json對象並用json對象接收
     */
    static void testJSONObjectUpload(){
        String url = "http://127.0.0.1:8090/kty/test/receiveHttpClientJSONObject";
        doPostJSONObject(url, getJsonObj(), getJsonArray());
    }

文件和參數的 發送 和 接收  ,接收的時候要對應key value
 

testFileParamUpload

發送 httpClient 請求:

 
    /**
     * httpclient
     * 發送文件和部分參數
     *
     * @return
     */
    public static String doPostFileAndParam(String url, List<Map<String, Object>> fileList, Map<String, Object> param) {
        String result = "";
        //新建一個httpclient
        CloseableHttpClient httpclient = HttpClients.createDefault();
 
        try {
            //新建一個Post請求
            HttpPost httppost = new HttpPost(url);
            //新建文件對象
            MultipartEntityBuilder reqEntity = MultipartEntityBuilder.create();
            ContentType contentType = ContentType.create("text/plain", "UTF-8");
            //添加參數的時候,可以都使用addPart,然後new一個對象StringBody、FileBody、BinaryBody等
            reqEntity
                    //設置編碼,這兩個一定要加,不然文件的文件名是中文就會亂碼
                    .setCharset(Charset.forName("utf-8"))
                    //默認是STRICT模式,用這個就不能使用自定義的編碼了
                    .setMode(HttpMultipartMode.BROWSER_COMPATIBLE)//也可以使用reqEntity.setLaxMode();具體的可以查看MultipartEntityBuilder類
                    //這個方法其實就是addPart(name, new StringBody(text, contentType));
                    .addTextBody("paramString", param.get("paramString").toString())
                    //textbody傳送的都是String類型,所以接收只能用string接收,接收後轉成json對象就可以了(後面一種方法直接可以用JSONObject接收,不論參數名)
                    .addTextBody("paramJSONObject", param.get("paramJSONObject").toString(), ContentType.APPLICATION_JSON)
                    .addTextBody("paramJSONArray", param.get("paramJSONArray").toString(), ContentType.APPLICATION_JSON)
                    //如果contentType不夠用,可以自己定義
                    .addPart("paramPart", new StringBody("addPart你好", contentType));
            //拼接文件類型
            for (Map<String, Object> elem : fileList) {//拼接參數
                String location = elem.get("location").toString();
                String fileName = elem.get("fileName").toString();
                System.out.println(fileName);
                File file = new File(location);
                //添加二進制內容,這個方法可以放流進去,也可以放文件對象進去,很方便
                InputStream fileStream = new FileInputStream(file);
                reqEntity.addBinaryBody("file", fileStream, ContentType.APPLICATION_OCTET_STREAM, fileName);
                //文件的Contenttype貌似只要合理就行,流、form_data、或者乾脆不填
//                reqEntity.addBinaryBody("file", file, ContentType.APPLICATION_OCTET_STREAM, fileName);
                //也可以用addPart添加
//                reqEntity.addPart("file", new FileBody(file));
            }
 
            //將數據設置到post請求裏
            httppost.setEntity(reqEntity.build());
 
            //執行提交
            System.err.println("執行請求:" + httppost.getRequestLine());
            CloseableHttpResponse response = httpclient.execute(httppost);
 
            //獲得返回參數
            InputStream is = response.getEntity().getContent();
            BufferedReader in = new BufferedReader(new InputStreamReader(is));
            StringBuffer buffer = new StringBuffer();
            String line = "";
            while ((line = in.readLine()) != null) {
                buffer.append(line);
            }
            result = buffer.toString();
            System.out.println("收到的返回:" + result);
 
            //關閉返回
            response.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                //關閉httpclient
                httpclient.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
 
        return result;
    }

接收:

 
    /**
     * httpclient 接收文件
     * 文件需要從request裏解析,可以自己手動解析,也可以像我這樣直接用multirequest接收,然後用getFiles就能拿到文件
     * 其他參數String類型
     *
     * @return
     * @RequestBody 加了這個才能區分,不然默認都是String的key value格式,會報mismatch arguments
     */
    @PostMapping("/receiveHttpClientWithFile")
    public String receiveHttpClientWithFile(
            MultipartHttpServletRequest multiRequest, String paramString, String paramPart,
            String paramJSONObject, String paramJSONArray) {
        String result = "成功收到請求";
        System.out.println("收到請求,開始執行");
        System.out.println("paramString===" + paramString);
        System.out.println("paramPart===" + paramPart);
 
        //這裏就可以解析string爲json對象
        System.out.println("paramJSONObject===" + paramJSONObject);
        JSONObject resJsonObj = JSONObject.fromObject(paramJSONObject);
        System.out.println("json對象裏的第一個元素token===" + resJsonObj.get("token"));
 
        //這裏就可以解析string爲jsonarray數組
        System.out.println("paramJSONArray===" + paramJSONArray);
        JSONArray resJsonArray = JSONArray.fromObject(paramJSONArray);
        System.out.println(resJsonArray.get(1));
 
        List<MultipartFile> fileList = multiRequest.getFiles("file");
        for (MultipartFile elem : fileList) {
            System.out.println(elem.getOriginalFilename());
            System.out.println("file===" + elem.getOriginalFilename() + "--" + elem.getSize() + elem.getContentType());
        }
 
 
        return result;
    }

請求輸出:

接收輸出:

json對象的 發送 和 接收 ,接收方用 @RequestBody,無視對應key

testJSONObjectUpload()

發送 httpClient :

 
    /**
     * httpclient
     * 發送json對象
     * StringEntity可以直接用JSONObject接收
     *
     * @return
     */
    public static String doPostJSONObject(String url, JSONObject jsonObject, JSONArray jsonArray) {
 
        String result = "";
        //新建一個httpclient
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            //新建一個Post請求
            HttpPost httppost = new HttpPost(url);
            //新建json對象
            StringEntity stringEntity = new StringEntity(jsonObject.toString(), ContentType.APPLICATION_JSON);
            // StringEntity stringEntity = new StringEntity(jsonArray.toJSONString(), ContentType.APPLICATION_JSON);
            //將數據設置到post請求裏
            httppost.setEntity(stringEntity);
 
            //執行提交
            System.err.println("執行請求:" + httppost.getRequestLine());
            CloseableHttpResponse response = httpclient.execute(httppost);
 
            //獲得返回參數
            InputStream is = response.getEntity().getContent();
            BufferedReader in = new BufferedReader(new InputStreamReader(is));
            StringBuffer buffer = new StringBuffer();
            String line = "";
            while ((line = in.readLine()) != null) {
                buffer.append(line);
            }
            result = buffer.toString();
            System.out.println("收到的返回:" + result);
 
            //關閉返回
            response.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                //關閉httpclient
                httpclient.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
 
        return result;
    }

接收:

    /**
     * httpclient 接收json對象
     *
     * @return
     */
    @PostMapping("/receiveHttpClientJSONObject")
    public String receiveHttpClientJSONObject(@RequestBody JSONObject param) {
        String result = "成功收到請求";
        System.out.println("收到請求,開始執行");
 
        System.out.println("param===" + param);
        System.out.println("json對象裏的第一個元素token===" + param.get("token"));
 
        return result;
    }

發送方控制檯打印:

接收方控制檯打印:

————————————————————————————————————————

綜上,代碼原文鏈接:https://blog.csdn.net/akxj2022/article/details/88691698

————————————————————————————————————————

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章