Okhttp基礎使用篇

官網 https://square.github.io/okhttp/

github地址 https://github.com/square/okhttp

 

okhttp4.x和okhttp3.x

4.x使用kotlin來編寫的

 

基本概念

Request

Request類封裝了請求報文信息:請求的Url地址、請求的方法(如GET、POST等)、各種請求頭(如Content-Type、Cookie)以及可選的請求體。一般通過內部類Request.Builder的鏈式調用生成Request對象。

 

Call

Call代表了一個實際的HTTP請求,它是連接Request和Response的橋樑,通過Request對象的newCall()方法可以得到一個Call對象。Call對象既支持同步獲取數據,也可以異步獲取數據。

執行Call對象的execute()方法,會阻塞當前線程去獲取數據,該方法返回一個Response對象。

執行Call對象的enqueue()方法,不會阻塞當前線程,該方法接收一個Callback對象,當異步獲取到數據之後,會回調執行Callback對象的相應方法。如果請求成功,則執行Callback對象的onResponse方法,並將Response對象傳入該方法中;如果請求失敗,則執行Callback對象的onFailure方法。

 

Response

Response類封裝了響應報文信息:狀態嗎(200、404等)、響應頭(Content-Type、Server等)以及可選的響應體。可以通過Call對象的execute()方法獲得Response對象,異步回調執行Callback對象的onResponse方法時也可以獲取Response對象。

 

目標明細

   使用OkHttp執行get請求和帶參數的get請求;

  使用OkHttp執行post請求、帶參數的post請求;

  支持contentType爲none、application/json、form-data、application/x-www-form-urlencoded

  圖從postman截取

代碼實現如下

 getUrl 方法: 用於拼接url、post或者get請求都可能會需要拼接url;url結尾?

                     後面的參數 Spring註解@requestParam獲取此參數;

                      Okhttp拼接功能蠻強大,沒有?會添加?拼接;有?會直接在後面添加參數。

curl -X GET "http://localhost:9099/requestDemo/getDemo?name=111&strDemo=222" -H "accept: */*"

      getBody方法:用於拼接post請求的body內容;

       

@Slf4j
public class OkhttpUtils {

   private static OkHttpClient okHttpClient = new OkHttpClient.Builder().readTimeout(6, TimeUnit.SECONDS).build();

   private static final MediaType JSON = MediaType.parse("application/json");

   private static final String MEDIATYPE_NONE = "none";
   private static final String MEDIATYPE_JSON = "application/json";
   private static final String MEDIATYPE_FORM = "form-data";
   private static final String MEDIATYPE_FORM_URLENCODED = "application/x-www-form-urlencoded";

    /**
      * @Author JackZhou
      * @Description  執行get請求
     **/
    public static String execRequest(String url, Map<String, String> headers){
        Request.Builder requestBuilder = new Request.Builder().url(url);
        if(headers != null && headers.size() >0 ){
            headers.entrySet().stream().forEach(entry -> requestBuilder.header(entry.getKey(), entry.getValue()));
        }
        Request request = requestBuilder.url(url).build();
        try {
            Response response = okHttpClient.newCall(request).execute();
            return  response.body().string();
        } catch (IOException e) {
            log.info("執行http請求出錯,地址:{}", url, e);
            return null;
        }
    }

    /**
     * @Author JackZhou
     * @Description  執行post請求
     **/
    public static String execPostRequest(String url, Map<String, String> headers, RequestBody requestBody){
        Request.Builder requestBuilder = new Request.Builder().url(url);
        if(headers != null && headers.size() >0 ){
            headers.entrySet().stream().forEach(entry -> requestBuilder.header(entry.getKey(), entry.getValue()));
        }
        Request request = requestBuilder.url(url).post(requestBody).build();
        try {
            Response response = okHttpClient.newCall(request).execute();
            return  response.body().string();
        } catch (IOException e) {
            log.info("執行http請求出錯,地址:{}", url, e);
            return null;
        }
    }

    /**
     * @Author JackZhou
     * @Description  得到post請求的RequestBody
     **/
    public static RequestBody getBody(String type, Map<String, String> formParam, String body){
        switch (type) {
            case MEDIATYPE_JSON:
                if(StringUtils.isEmpty(body)){
                    RequestBody.create(null, "");
                }
                return RequestBody.create(JSON, body);
            case MEDIATYPE_FORM:
                MultipartBody.Builder formBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
                if(formParam != null && formParam.size() >0 ){
                    formParam.entrySet().stream().forEach(entry -> formBuilder.addFormDataPart(entry.getKey(), entry.getValue()));
                }
                return formBuilder.build();
            case MEDIATYPE_FORM_URLENCODED:
                FormBody.Builder builder = new FormBody.Builder();
                if(formParam != null && formParam.size() >0 ){
                    formParam.entrySet().stream().forEach(entry -> builder.add(entry.getKey(), entry.getValue()));
                }
                return builder.build();
            case MEDIATYPE_NONE:
                return RequestBody.create(null, "");
            default:
                throw new IllegalArgumentException("不支持的mediaType:" + type);
        }
    }

    /**
     * @Author JackZhou
     * @Description  得到拼接後的url  @RequestParam參數
     **/
    public static String getUrl(String url, Map<String, String> params){
        HttpUrl.Builder builder = HttpUrl.parse(url).newBuilder();
        if(params != null && params.size() > 0){
            params.entrySet().stream().forEach(entry -> builder.addQueryParameter(entry.getKey(), entry.getValue()));
        }
        return builder.build().toString();
    }

注意點,如果post請求的內容爲空,不能傳空的requestBody會報錯  

java.lang.IllegalArgumentException: method POST must have a request body 

#如果post請求的body和contentType爲空
RequestBody.create(null, "")

測試驗證

@Data
public class Person {
    private String id;
    private String name;
    private int age;
}
@RestController
@Api(tags = "模擬不同的meidaType")
@RequestMapping(value = "/requestDemo")
public class MediaTypeController {

    @ApiOperation("模擬普通get請求")
    @RequestMapping(value = "/getDemo", method = RequestMethod.GET)
    public String getDemo(@RequestParam(required = false) String name, @RequestParam(required = false) String strDemo){
        return "success: " + name + ";strDemo:" + strDemo;
    }

    @ApiOperation("模擬普通post請求")
    @RequestMapping(value = "/getPost", method = RequestMethod.POST)
    public String postDemo(){
        return "success";
    }

    @ApiOperation("模擬普通post 帶參數請求")
    @RequestMapping(value = "/getPostParam", method = RequestMethod.POST)
    public String postParamDemo(@RequestParam(required = false) String name, @RequestParam(required = false) String strDemo){
        return "success:" + name;
    }

    @ApiOperation("模擬post xxx-form請求")
    @RequestMapping(value = "/getPostModel", method = RequestMethod.POST)
    public String postModelDemo(@ModelAttribute Person person){
        if(person != null){
            return "success:" + person.getName();
        }else{
            return "success";
        }
    }

    @ApiOperation("模擬普通post 傳json請求")
    @RequestMapping(value = "/getPostJson", method = RequestMethod.POST)
    public String postJsonDemo(@RequestBody Person person){
        if(person != null){
            return "success:" + person.getName();
        }else{
            return "success";
        }
    }

    @ApiOperation("模擬普通post form請求")
    @RequestMapping(value = "/getPostForm", method = RequestMethod.POST)
    public String postDemo(HttpServletRequest request){
        System.out.println(request.getParameter("name"));
        System.out.println(request.getParameter("strDemo"));
        return "success";
    }

}

偷懶,測試main方法;加到OkhttpUtils類中即可

  public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("name", "張三");
        map.put("strDemo", "上山打老虎");

        Map<String, String> pMap = new HashMap<>();
        pMap.put("name", "張三");
        pMap.put("id", "11111");
        pMap.put("age", "111");

          // 測試get請求、有參無參均可
//        String getUrl = "http://localhost:9099/requestDemo/getDemo";
//        log.info(execRequest(getUrl(getUrl, map), null));
          // 測試基本的post  url後面有參數或者沒有
//        String postUrl = "http://localhost:9099/requestDemo/getPost";
//        //String postUrl = "http://localhost:9099/requestDemo/getPostParam";
//        log.info(execPostRequest(postUrl, null, getBody(MEDIATYPE_NONE, null, null)));
//        log.info(execPostRequest(execRequest(getUrl(getUrl, map), null, getBody(MEDIATYPE_NONE, null, null)));

         // 測試post的application/x-www-form-urlencoded 對應@ModelAttribute註解
//        String postUrl = "http://localhost:9099/requestDemo/getPostModel";
//        //log.info(execPostRequest(postUrl, null, getBody(MEDIATYPE_FORM_URLENCODED, null, null)));
//        log.info(execPostRequest(postUrl, null, getBody(MEDIATYPE_FORM_URLENCODED, pMap, null)));
            // 測試post的application/json  對應@RequestBody註解
//         String postUrl = "http://localhost:9099/requestDemo/getPostJson";
//         log.info(execPostRequest(postUrl, null, getBody(MEDIATYPE_JSON, null, "{ \"age\": 11, \"id\": \"sdsb111\", \"name\": \"張三\"}")));
           // 測試post的form-data
//         String postUrl = "http://localhost:9099/requestDemo/getPostForm";
//         log.info(execPostRequest(postUrl, null, getBody(MEDIATYPE_FORM, map, null)));

    }

 

 

 

 

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