java模擬http請求,通過流的方式發送數據,模擬接收流文件和json數據

項目裏碰到過模擬ajax請求的案例,研究了一下,覺得 httpClient 是真心好用,由於模擬環境搞了大半天,httpclient就另外再寫博文吧

下面的例子介紹流的方式發送和接收,這個就有點暴力了,想傳啥都行:以字節流的方式發送數據(可以是任何數據)

看標題就知道了,簡單粗暴的方法,管他什麼格式,統統“流”過去,不過既然是模擬的,要配置好其他參數,對方纔能正常接收到

發送方:

    /**
     * 以流的方式
     * 發送文件和json對象
     *
     * @return
     */
    public static String doPostFileStreamAndJsonObj(String url, List<String> fileList, JSONObject json) {
        String result = "";//請求返回參數
        String jsonString = json.toJSONString();//獲得jsonstirng,或者toString都可以,只要是json格式,給了別人能解析成json就行
//        System.out.println("================");
//        System.out.println(xml);//可以打印出來瞅瞅
//        System.out.println("================");
        try {
            //開始設置模擬請求的參數,額,不一個個介紹了,根據需要拿
            String boundary = "------WebKitFormBoundaryUey8ljRiiZqhZHBu";
            URL u = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) u.openConnection();
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("connection", "Keep-Alive");
            //這裏模擬的是火狐瀏覽器,具體的可以f12看看請求的user-agent是什麼
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Charsert", "UTF-8");
            //這裏的content-type要設置成表單格式,模擬ajax的表單請求
            conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
            // 指定流的大小,當內容達到這個值的時候就把流輸出
            conn.setChunkedStreamingMode(10240000);
            //定義輸出流,有什麼數據要發送的,直接後面append就可以,記得轉成byte再append
            OutputStream out = new DataOutputStream(conn.getOutputStream());
            byte[] end_data = ("\r\n--" + boundary + "--\r\n").getBytes();// 定義最後數據分隔線

            StringBuilder sb = new StringBuilder();
            //添加form屬性
            sb.append("--");
            sb.append(boundary);
            sb.append("\r\n");
            //這裏存放要傳輸的參數,name = xml
            sb.append("Content-Disposition: form-data; name=\"JsonObj\"");
            sb.append("\r\n\r\n");
            //把要傳的json字符串放進來
            sb.append(jsonString);
            out.write(sb.toString().getBytes("utf-8"));
            out.write("\r\n".getBytes("utf-8"));

            int leng = fileList.size();
            for (int i = 0; i < leng; i++) {
                File file = new File(fileList.get(i));
                if(file.exists()){
                    sb = new StringBuilder();
                    sb.append("--");
                    sb.append(boundary);
                    sb.append("\r\n");
                    //這裏的參數啥的是我項目裏對方接收要用到的,具體的看你的項目怎樣的格式
                    sb.append("Content-Disposition: form-data;name=\"File"
                            + "\";filename=\"" + file.getName() + "\"\r\n");
                    //這裏拼接個fileName,方便後面用第一種方式接收(如果是純文件,不帶其他參數,就可以不用這個了,因爲Multipart可以直接解析文件)
                    sb.append("FileName:"+ file.getName() + "\r\n");
                    //發送文件是以流的方式發送,所以這裏的content-type是octet-stream流
                    sb.append("Content-Type:application/octet-stream\r\n\r\n");
                    byte[] data = sb.toString().getBytes();
                    out.write(data);
                    DataInputStream in = new DataInputStream(new FileInputStream(file));
                    int bytes = 0;
                    byte[] bufferOut = new byte[1024];
                    while ((bytes = in.read(bufferOut)) != -1) {
                        out.write(bufferOut, 0, bytes);
                    }
                    int j = i + 1;
                    if (leng > 1 && j != leng) {
                        out.write("\r\n".getBytes()); // 多個文件時,二個文件之間加入這個
                    }
                    in.close();
                }else{
                    System.out.println("沒有發現文件");
                }
            }
            //發送流
            out.write(end_data);
            out.flush();
            out.close();
            // 定義BufferedReader輸入流來讀取URL的響應
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    conn.getInputStream()));
            String line = "";
            while ((line = reader.readLine()) != null) {
                result += line;
            }
//            System.out.println("================");
//            System.out.println(result.toString());//可以把結果打印出來瞅瞅
//            System.out.println("================");
            //後面可以對結果進行解析(如果返回的是格式化的數據的話)
        } catch (Exception e) {
            System.out.println("發送POST請求出現異常!" + e);
            e.printStackTrace();
        }
        return result;
    }
   public static void main(String args[]) throws Exception {
        //模擬流文件及參數上傳
        String url = "http://127.0.0.1:8090/kty/test/receiveStream";
        //文件列表,搞了三個本地文件
        List<String> fileList = new ArrayList<>();
        fileList.add("F:\\me\\photos\\動漫\\3ba39425fec1965f4d088d2f.bmp");
        fileList.add("F:\\me\\photos\\動漫\\09b3970fd3f5cc65b1351da4.bmp");
        fileList.add("F:\\me\\photos\\動漫\\89ff57d93cd1b72cd0164ec9.bmp");
        //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 json = JSONObject.parseObject(jsonString);
        doPostFileStreamAndJsonObj(url, fileList, json);
    }

因爲是流的方式,所以要從http請求裏獲取body,然後再解析

接收方:


@RestController
@RequestMapping("/test")
//跨域註解
@CrossOrigin
public class TestController {

    /**
     * 接收流信息
     *
     * @param request
     * @return
     */
    @PostMapping("/receiveStream")
    public String receiveStream(HttpServletRequest request) {
        String result = "";
        System.out.println("進來了");
        try {
            //獲取request裏的所有部分
            Collection<Part> parts = request.getParts();
            for (Iterator<Part> iterator = parts.iterator(); iterator.hasNext(); ) {
                Part part = iterator.next();
                System.out.println("名稱========" + part.getName());
                if ("JsonObj".equals(part.getName())) {
                    //解析json對象
                    BufferedReader reader = new BufferedReader(new InputStreamReader(part.getInputStream()));
                    String line = "";
                    String parseString = "";
                    while ((line = reader.readLine()) != null) {
                        parseString += line;
                    }
                    JSONObject json = JSONObject.parseObject(parseString);
                    System.out.println("接收到的json對象爲=====" + json.toJSONString());
                } else if ("File".equals(part.getName())) {
                    String fileName = "";
                    Long size = part.getSize();
                    //文件名的獲取,可以直接獲取header裏定義好的FIleName(大部分沒有),或從Content-Disposition去剪切出來
//                    String head = part.getHeader("Content-Disposition");
//                    fileName = head.substring(head.indexOf("filename=")+ 10, head.lastIndexOf("\""));
                    fileName = part.getHeader("FileName");
                    System.out.println(fileName + size);
//                    //這裏就是文件,文件流就可以直接寫入到文件了
//                    InputStream inputStream = part.getInputStream();
//                    OutputStream outputStream = new FileOutputStream(fileName);
//                    int bytesWritten = 0;
//                    int byteCount = 0;
//                    byte[] bytes = new byte[1024];
//                    while ((byteCount = inputStream.read(bytes)) != -1) {
//                        outputStream.write(bytes, bytesWritten, byteCount);
//                        bytesWritten += byteCount;
//                    }
//                    inputStream.close();
//                    outputStream.close();
                }
            }

            //如果嫌上面獲取文件的麻煩,用下面這個比較簡單,解析成multipartFile
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            //統計文件數
            Integer fileCount = 0;
            //請求裏key爲File的元素(即文件元素)
            List<MultipartFile> list = multiRequest.getFiles("File");
            while (fileCount < list.size()) {
                MultipartFile file = list.get(fileCount);
                System.out.println(file.getName());
                System.out.println(file.getOriginalFilename());
                System.out.println(file.getSize());
                fileCount++;
            }
            System.out.println("共有" + fileCount + "個文件");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
}

控制檯輸出:

 

流的方式到這裏就結束了,

httpclient的方式稍後再寫

如果模擬的時候有相關參數不瞭解,可以瀏覽器打開隨便一個網頁,f12看看傳的參數都有哪些,例如:

歡迎留言指正

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