通过httpclient发送请求的几种方式,发送文件、参数、json对象

使用工具: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> getFileList() {
        //文件列表,搞了三个本地文件
        List> fileList = new ArrayList<>();
        Map filedetail1 = new HashMap<>();
        filedetail1.put("location", "F:\\me\\photos\\动漫\\3ba39425fec1965f4d088d2f.bmp");
        filedetail1.put("fileName", "图片1");
        fileList.add(filedetail1);
        Map filedetail2 = new HashMap<>();
        filedetail2.put("location", "F:\\me\\photos\\动漫\\09b3970fd3f5cc65b1351da4.bmp");
        filedetail2.put("fileName", "图片2");
        fileList.add(filedetail2);
        Map 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,做好数据之后解析成json,.toJSONString
         * 3.new 一个JSONObject对象,然后自己拼接
         * 下面的例子用map好了,这个应该通俗易懂
         */
        Map main = new HashMap<>();
        main.put("token", "httpclient with file stringParam jsonParam and jasonArrayParam");
        List> contentList = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            Map 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> contentList = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            Map 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 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> fileList, Map 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 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 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;
    }

请求输出:

通过httpclient发送请求的几种方式,发送文件、参数、json对象_第1张图片

接收输出:

通过httpclient发送请求的几种方式,发送文件、参数、json对象_第2张图片

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;
    }

发送方控制台打印:

通过httpclient发送请求的几种方式,发送文件、参数、json对象_第3张图片

接收方控制台打印:

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

综上,代码原文链接:https://blog.csdn.net/akxj2022/article/details/88691698

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

你可能感兴趣的:(Java,Web)