HttpUtils 詳解

带刺的坐椅發表於2024-10-17

一、詳解

1.1 介紹

現如今的 Web 專案,由服務端向外發起網路請求的場景,基本上隨處可見!
傳統情況下,在服務端程式碼裡訪問 http 服務時,一般會使用 JDK 的 HttpURLConnection 或者 Apache 的 HttpClient,不過這種方法使用起來太過繁瑣,而且 api 使用起來非常的複雜,還得操心資源回收。

1.2 什麼是 HttpUtils?

  • HttpUtils 是 Solon 提供的進行遠端呼叫客戶端
  • HttpUtils 提供了很多遠端呼叫的方法,能夠大大提高客戶端的編寫效率。 HttpUtils 介面實現了 HttpURLConnection 的適配(預設),以及 OkHttp 的適配。
  • 官網地址: solon-net-httputils

1.3 引入依賴

<dependency>
    <groupId>org.noear</groupId>
    <artifactId>solon-net-httputils</artifactId>
</dependency>

HttpUtils 不需要初始化,即可直接使用。而且,可以直接使用負載均衡的能力(需要引入 solon-cloud 的外掛,提供底層支援)。像這樣:

HttpUtils.http("user-service", "/user/get?id=1").get();

二、介面使用

HttpUtils 最大的特色就是對各種網路請求方式做了包裝,能極大的簡化開發人員的工作量,下面我們以 GET、POST、PUT、DELETE、檔案上傳與下載為例,分別介紹各個API的使用方式。

2.1 GET 請求

透過 HttpUtils 傳送 HTTP GET 協議請求,經常使用到的方法有兩個:

  • get() -> String
  • getAs(Type type) -> T (支援泛型)

在 Solon 環境下寫一個單元測試用例,首先建立一個 Api 介面,然後編寫單元測試進行服務測試。

不帶參的get請求

@Controller
public class TestController {
    @Get
    @Mapping("testGet")
    public Result testGet(){
        Result result = new Result();
        result.setCode("200");
        result.setMsg("demo...");
        return result;
    }
}

@Data
public class Result {
    private String code;
    private String msg;
}

單元測試(不帶參的get請求)

@Test
public void testGet(){
    //請求地址
    String url = "http://localhost:8080/testGet";
 
    //發起請求,直接返回物件
    Result result = HttpUtils.http(url).getAs(Result.class);
    System.out.println(result.toString());

帶參的get請求(使用佔位符號傳參)

@Controller
public class TestController {
    @Get
    @Mapping("testGetByRestFul/{id}/{name}")
    public Result testGetByRestFul(@Path("id") String id, @Path("name") String name){
        Result result = new Result();
        result.setCode("200");
        result.setMsg("demo...");
        return result;
    }
}

單元測試(帶參的get請求),順帶加了個 header 資訊。

@Test
public void testGetByRestFul(){
    //請求地址
    String url = "http://localhost:8080/testGetByRestFul/001/張三";
 
    //發起請求,直接返回物件(restful風格)
    Result result = HttpUtils.http(url).header("App-Id","1").getAs(Result.class);
    System.out.println(result.toString());
}

2.2 POST 請求

其實 POST 請求方法和 GET 請求方法上大同小異,HttpUtils 的 POST 請求也包含兩個主要方法:

  • post() -> String
  • postAs(Type type) -> T(支援泛型)

模擬表單請求,post方法測試

@Controller
public class TestController {
    @Post
    @Mapping("testPostByForm")
    public Result testPostByForm(String userName, String userPwd){
        Result result = new Result();
        result.setCode("200");
        result.setMsg("Demo...");
        return result;
    }
}

x-www-form-urlencoded post

@Test
public void testPostByForm(){
    //請求地址
    String url = "http://localhost:8080/testPostByForm";
 
    //發起請求
    Result result = HttpUtils.http(url)
                             .data("userName", "唐三藏")
                             .data("userPwd", "123456")
                             .postAs(Result.class);
                  
    System.out.println(result.toString());
}

form-data post,順帶加上檔案上傳

@Test
public void testPostByForm(){
    //請求地址
    String url = "http://localhost:8080/testPostByForm";
 
    //發起請求
    Result result = HttpUtils.http(url)
                             .data("userName", "唐三藏")
                             .data("userPwd", "123456")
                             .data("file", "logo.jpg", new File("/data/logo.jpg")) 
                             .postAs(Result.class, true); //useMultipart = true
                  
    System.out.println(result.toString());
}

json-body post

@Test
public void testPostByForm(){
    //請求地址
    String url = "http://localhost:8080/testPostByForm";
 
    //發起請求
    Result result = HttpUtils.http(url)
                             .bodyOfJson("{\"userName\":\"唐三藏\",\"userPwd\":\"123456\"}")
                             .postAs(Result.class); 
                  
    System.out.println(result.toString());
}

bean-body post

@Test
public void testPostByForm(){
    //請求地址
    String url = "http://localhost:8080/testPostByForm";
    
    UserBean user = new UserBean();
    user.setUserName("唐三藏");
    user.setUserPwd("123456")
 
    //發起請求
    Result result = HttpUtils.http(url)
                             .bodyOfBean(user)
                             .postAs(Result.class); 
                  
    System.out.println(result.toString());
}

2.3 PUT、PATCH、DELETE 請求

用法與 POST 完全相同。

2.4 高階用法

獲取響應(用完要關閉)

try(HttpResponse resp = HttpUtils.http("http://localhost:8080/hello").data("name","world").exec("POST")) {
    int code = resp.code();
    String head = resp.header("Demo-Header");
    String body = resp.bodyAsString();
}

配置序列化器。預設為 json,改為 fury;或者自己定義。

FuryBytesSerializer serializer = new FuryBytesSerializer();

Result body = HttpUtils.http("http://localhost:8080/book")
                       .serializer(serializer)
                       .bodyOfBean(book)
                       .postAs(Result.class);