Use of HttpClient and RestTemplate (detailed comparison)

Article Directory

 

Use of HttpClient and RestTemplate (detailed comparison)


Among the interfaces allocated today, there are a few that need to call third-party interface data. I don’t know anything about it, starting from scratch

One, HttpClient

First import dependencies

<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.13</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.testng/testng -->
<dependency>
    <groupId>org.testng</groupId>
    <artifactId>testng</artifactId>
    <version>7.0.0</version><!--注释掉spring自带的依赖, 最新版本7.3.0会报错, 选了低版本的7.0.0-->
    <scope>test</scope>
</dependency>

 

1. get without parameters

    @Test //get 无参
    public void doGet() {
    	String uri = "https://openapi.chanjet.com/auth/refreshToken?grantType=refresh_token&appKey=K2vIOn4m&refreshToken=1";
        // 1.创建Http客户端
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        // 2.创建Get请求
        HttpGet request = new HttpGet(uri);
        // 3.响应模型
        CloseableHttpResponse response = null;
        try {
            // 3.执行Get请求
            response = httpClient.execute(request);
            // 4.从响应模型中获取响应实体
            HttpEntity responseEntity = response.getEntity();
            System.out.println("响应状态为:" + response.getStatusLine());
            if (responseEntity != null) {
                System.out.println("响应内容长度为:" + responseEntity.getContentLength());
                System.out.println("响应内容为:" + EntityUtils.toString(responseEntity, StandardCharsets.UTF_8));
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (httpClient != null) {
                    httpClient.close();
                }
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

Print output:
Insert picture description here

 

2. get with parameters

Request address  https://dev.chanjet.com/docs/common/app_settled/app_settled_auth

    @Test //get 有参
    public void doGetParam() {
        // 1.创建Http客户端
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        // 2.封装参数
        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("grantType", "authorization_code"));
        params.add(new BasicNameValuePair("appKey", "K2vIOn4m"));
        params.add(new BasicNameValuePair("redirectUri", "https://baidu.com"));
        params.add(new BasicNameValuePair("code", "1"));
        // 3.创建uri
        URI uri = null;
        try {
            uri = new URIBuilder().setScheme("https")
                    .setHost("openapi.chanjet.com")
                    .setPath("/auth/getToken")
                    .setParameters(params).build();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }		
        // 4.创建请求
        HttpGet request = new HttpGet(uri);
        CloseableHttpResponse response = null;
        try {
            
            // 5.执行Get请求
            response = httpClient.execute(request);
            // 6.获取响应实体
            HttpEntity entity = response.getEntity();
            System.out.println("响应状态为:" + response.getStatusLine());
            if (entity != null) {
                System.out.println("响应内容长度为:" + entity.getContentLength());
                String entityStr = EntityUtils.toString(entity, StandardCharsets.UTF_8);
                System.out.println("响应内容为:" + entityStr);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (httpClient != null) {
                    httpClient.close();
                }
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

Request address:

https://openapi.chanjet.com/auth/getToken?grantType=authorization_code&appKey=K2vIOn4m&redirectUri=https://baidu.com&code=ffb20d9c95e5410896c8270e49ccd43c

Print output:

Insert picture description here

 

3. Post object

    @Test //post 对象
    public void postObject() {
    	// 如果有普通参数,uri 改成 URIBuilder
        String uri = "http://localhost:8080/people/addPeople";
        // 创建Http客户端
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();        
		// 创建Post请求
        HttpPost request = new HttpPost(uri);
        request.setHeader("Content-Type", "application/json;charset=utf8");
		// 添加json对象
        People people = new People();
        people.setName("张飞");
        people.setCreateTime(LocalDateTime.now());
        String jsonString = JSON.toJSONString(people);

        StringEntity entity = new StringEntity(jsonString, "UTF-8");
        httpPost.setEntity(entity);


        // 响应模型
        CloseableHttpResponse response = null;
        try {
            // 执行Post请求
            response = httpClient.execute(request);
            // 从响应模型中获取响应实体
            HttpEntity responseEntity = response.getEntity();
            System.out.println("响应状态为:" + response.getStatusLine());
            if (responseEntity != null) {
                System.out.println("响应内容长度为:" + responseEntity.getContentLength());
                System.out.println("响应内容为:" + EntityUtils.toString(responseEntity, StandardCharsets.UTF_8));
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (httpClient != null) {
                    httpClient.close();
                }
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

Request interface:

    @ApiOperation(value = "添加", notes = "添加用户")
    @PostMapping("/addPeople")
    public String addPeople(@RequestBody People people) {
        int row = peopleService.add(people);
        return row == 1 ? "添加成功" : "添加失败";
    }

Print output:
Insert picture description here

 

4. Close the console log

Create logback.xml under resource


<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
  <!-- definition of appender STDOUT -->
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
    </encoder>
  </appender>
 
  <root level="ERROR">
    <!-- appender referenced after it is defined -->
    <appender-ref ref="STDOUT"/>
  </root> 
</configuration>

 

Insert picture description here

 

Two, RestTemplate

1. How to use

1) Initiate a request

  • get request

    • getForObject()
      sends an HTTP GET request, and the returned request body will be mapped to an object

    • getForEntity()
      sends an HTTP GET request, and the returned ResponseEntity contains the object mapped into the response body

RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> entity = restTemplate.getForEntity(uri, String.class);
// TODO 处理响应
  • Post request method
    • postForEntity()
      POSTs data to a URL and returns a ResponseEntity containing an object, which is mapped from the response body.

    • postForObject()
      POSTs data to a URL and returns an object formed according to the response body matching.

    • postForLocation()
      POST data to a URL and return the URL of the newly created resource

RestTemplate restTemplate = new RestTemplate();
// headers
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
HttpEntity<Object> objectHttpEntity = new HttpEntity<>(headers);

ResponseEntity<String> entity = restTemplate.postForEntity(uri, request, String.class);
// TODO 处理响应

2) Add timeout period

//设置超时时间
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setConnectTimeout(60 * 1000);
requestFactory.setReadTimeout(60 * 1000);
restTemplate.setRequestFactory(requestFactory);

3) Add headers

Only post requests have header parameters, get can be replaced by exchange

// herders
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
httpHeaders.add("openToken", openToken);
httpHeaders.add("appKey", chanJetKey);
httpHeaders.add("appSecret", chanJetSecret);
HttpEntity<JSONObject> request = new HttpEntity<>(httpHeaders);

4) Restful style url parameters

uri = "http://localhost:8080/people/selectById/{id}";
// params
Map<String, String> param = new HashMap<>();
param.put("id", XXX);
ResponseEntity<String> entity = restTemplate.getForEntity(uri, String.class, param);

5) Add get parameters

uri = "http://localhost:8080/people/selectById?id={id}&XXX={XXX}";
// params
Map<String, String> params = new HashMap<>();
params.put("id", XXX);
params.put("XXX", XXX);
ResponseEntity<String> entity = restTemplate.getForEntity(uri, String.class, params);

6) Add post request body

// body  post的请求体
JSONObject json = new JSONObject();
json.put("XXX", XXX);
json.put("XXX", XXX);
HttpEntity<JSONObject> request = new HttpEntity<>(json, httpHeaders);
ResponseEntity<String> entity = restTemplate.postForEntity(uri, request, String.class);

7) Call the third-party interface

//调用第三方api 若是服务返回状态码不为200,默认会执行DefaultResponseErrorHandler,返回 401 Unauthorized: [no body]
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());

try {// 发起请求
    ResponseEntity<String> entity = restTemplate.exchange(uri, HttpMethod.GET, request, String.class, params);
    // TODO 状态码200,处理业务逻辑
    
} catch (HttpClientErrorException e) {
	// TODO 状态码非200        
    byte[] responseBodyAsByteArray = e.getResponseBodyAsByteArray();// 返回的响应
    String bodyAsString = null;
    try {
        bodyAsString = new String(responseBodyAsByteArray, "UTF-8");
    } catch (UnsupportedEncodingException unsupportedEncodingException) {
        unsupportedEncodingException.printStackTrace();
    }
    // TODO...
    
}

The default character encoding of different Spring versions is different

  • spring-framework.version 5.2.9

Insert picture description here

  • spring-framework.version 4.3.9

Insert picture description here

2. Use case

1) get no parameters

    @Test // get 无参
    protected void get() {
        RestTemplate restTemplate = new RestTemplate();
        String uri = "http://localhost:8080/people/selectAll";

        //1.getForObject, 将返回的请求体 映射为一个对象
        String result = restTemplate.getForObject(uri, String.class);
        System.out.println(result);

        //2.getForEntity, 返回的ResponseEntity包含了响应体所映射成的对象
        ResponseEntity<String> entity = restTemplate.getForEntity(uri, String.class);
        System.out.println(entity);
    }

Printout

{查询成功:People(id=1, name=赵云, createTime=2020-10-19T20:39:14)}

<200,{查询成功:People(id=1, name=赵云, createTime=2020-10-19T20:39:14)},[Content-Type:"text/plain;charset=UTF-8", Content-Length:"72", Date:"Wed, 21 Oct 2020 14:40:08 GMT", Keep-Alive:"timeout=60", Connection:"keep-alive"]>

2)get @PathVariable

    @Test // get restful风格 @PathVariable
    protected void getRestful1() {
        RestTemplate restTemplate = new RestTemplate();
        String uri = "http://localhost:8080/people/selectById/{1}";

        String result = restTemplate.getForObject(uri, String.class, 1);
        System.out.println(result);
    }

    @Test // get restful风格 @PathVariable
    protected void getParam() {
        RestTemplate restTemplate = new RestTemplate();
        String uri = "http://localhost:8080/people/selectById/{id}";
        Map<String, String> params = new HashMap();
        params.put("id", "1");

        String result = restTemplate.getForObject(uri, String.class, params);
        System.out.println(result);
    }

Print output:

{查询成功:People(id=1, name=赵云, createTime=2020-10-19T20:39:14)}
  •  

Request interface:

@ApiOperation(value = "查询", notes = "通过id查询,restful风格")
@GetMapping("/selectById/{id}")
public String findById2(@PathVariable("id") Integer id) {
    People people = peopleService.findById(id);
    return people == null ? "{message:查询失败,人员不存在}" : "{查询成功:" + people + "}";
}

3)☆ get headers @PathVariable @RequestParam

The get request has no headers, use exchange instead

    /**
     * 畅捷通接口说明 应收统计表 https://dev.chanjet.com/docs/accounting/bb/ystjb
     */
    @Test // get 带参数 @PathVariable @RequestParam
    protected void yftjb() {
        ResponseResultNew resultNew = new ResponseResultNew(0,"请求成功");
        String uri = "https://sandbox-openapi.chanjet.com/accounting/gl/statistics/pay/{bookid}?period={period}";
        
        RestTemplate restTemplate = new RestTemplate();
        //调用第三方api 若是服务返回状态码不为200,默认会执行DefaultResponseErrorHandler
        restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
        
        // headers
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
        httpHeaders.add("openToken", access_token);
        httpHeaders.add("appKey", chanJetKey);
        httpHeaders.add("appSecret", chanJetSecret);
        // path
        Map<String, String> params = new HashMap<>();
        params.put("bookid", bookid);
        params.put("period", period);
        
        HttpEntity<Object> request = new HttpEntity<>(httpHeaders);
        
        try {// 发起请求
            ResponseEntity<String> entity = restTemplate.exchange(uri, HttpMethod.GET, request, String.class, params);
            // TODO 状态码200,处理业务逻辑
            YDZResponse ydzResponse = JSON.parseObject(entity.getBody(), YDZResponse.class);
            if (ydzResponse.getCode().equals("200")) {
                // TODO...
            } else {
                resultNew.setMessage(ydzResponse.getMsg()); // 返回错误信息
            }
        } catch (HttpClientErrorException e) {
            // TODO: 状态码非200
            byte[] responseBody = e.getResponseBodyAsByteArray();
            String bodyAsString = getResponseBodyAsString(responseBody, "UTF-8");
            YDZResponse ydzResponse = JSON.parseObject(bodyAsString, YDZResponse.class);
            resultNew.setCode(Integer.valueOf(ydzResponse.getCode()));
            resultNew.setMessage(ydzResponse.getMessage()); // 返回错误信息
        }
        log.info("执行结果 = {}", resultNew);
        return resultNew;
    }

Print output:

执行结果: ResponseResultNew(code=50004, message=appSecret不正确, data=, timestamp=1603869867229)


===============================================
Default Suite
Total tests run: 1, Passes: 1, Failures: 0, Skips: 0
===============================================

4)post @RequestParam

    @Test // post 带参数 @RequestParam
    public void post() {
        RestTemplate client = new RestTemplate();
        // headers
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        // params
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("id", "1");

        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers);
        ResponseEntity<People> response = client.postForEntity("http://localhost:8080/people/selectById", request, People.class);
        System.out.println(response.getBody());
    }

Print output:

People(id=1, name=赵云, createTime=2020-08-05T12:53:39)
  •  

Request address:

    @ApiOperation(value = "查询", notes = "通过id查询(Post)")
    @PostMapping("/selectById")
    public People findByIdPost(@RequestParam Integer id) {
        People people = peopleService.findById(id);
        return people;
    }

5)post @RequestBody

    @Test // post 带参数 @RequestBody
    public void postJSON() {
        RestTemplate client = new RestTemplate();
        // headers
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        // body
        JSONObject json = new JSONObject();
        json.put("id",1);
        // request
        HttpEntity<JSONObject> request = new HttpEntity<>(json, headers);
        ResponseEntity<String> response = client.postForEntity("http://localhost:8080/people/selectByPeople", request, String.class);
        System.out.println(response.getBody());
    }

Print output:

查询成功
  •  

Request interface:

    @ApiOperation(value = "查询", notes = "通过People查询")
    @PostMapping("/selectByPeople")
    public String findByPeople(@RequestBody People people) {
        People people2 = peopleService.findById(people.getId());
        return people2 == null ? "查询失败" : "查询成功";
    }

6)☆ post @RequestParam @RequsetBody

    /**
     * 易代账API https://dev.chanjet.com/docs/finance/ydzpj/fp
     */
    @Test // post @RequestBody, @RequestParam
    public void addInvoice() {
        ResponseResultNew resultNew = new ResponseResultNew(0, "请求成功");
        String uri1 = "https://openapi.chanjet.com/accounting/invoice/Invoice/{bookid}";
        String uri2 = "https://sandbox-openapi.chanjet.com/accounting/invoice/Invoice/{bookid}";

        RestTemplate client = new RestTemplate();
        //调用第三方api 若是服务返回状态码不为200,默认会执行DefaultResponseErrorHandler:  401 Unauthorized: [no body]
        client.setRequestFactory(new HttpComponentsClientHttpRequestFactory());

        // herders
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        httpHeaders.add("openToken", "openToken");
        httpHeaders.add("appKey", "appKey");
        httpHeaders.add("appSecret", "appSecret");
        // params
        Map<String, String> param = new HashMap<>();
        param.put("bookid", "1");
        // body
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("custVendor", "");
        //...

        HttpEntity<String> request = new HttpEntity<>(jsonObject.toJSONString(), httpHeaders);
        try {// 发起请求
            ResponseEntity<String> entity = client.postForEntity(uri2, request, String.class, param);
            // TODO 状态码200, 处理业务逻辑
            log.info("响应体 = {}", entity.getBody());
            YDZResponse ydzResponse = JSON.parseObject(entity.getBody(), YDZResponse.class);
            if (ydzResponse.getCode() == null) {
                resultNew.setData(JSON.toJSON(entity.getBody()));
            } else {
                resultNew.setCode(1);
                resultNew.setMessage(ydzResponse.getMsg()); // 返回错误信息
            }
        } catch (HttpClientErrorException e) {
        	// TODO 状态码非200
            String bodyAsString = e.getResponseBodyAsString();// spring5.2.9默认字符UTF-8
            YDZResponse ydzResponse = JSON.parseObject(bodyAsString, YDZResponse.class);
            System.out.println("返回结果: "+ydzResponse);
            resultNew.setCode(Integer.valueOf(ydzResponse.getCode()));
            resultNew.setMessage(ydzResponse.getMessage()); // 返回错误信息
        }
        System.out.println(resultNew);
    }

Print output:

返回结果: YDZResponse(code=50004, requestId=6b1fffed-232232, message=appSecret不正确, status=401, timestamp=2020-10-22T15:14:38.336)
ResponseResultNew(code=1, message=appSecret不正确, data=, timestamp=1603350883894)


===============================================
Default Suite
Total tests run: 1, Passes: 1, Failures: 0, Skips: 0
===============================================
  •  

Guess you like

Origin blog.csdn.net/xiaokanfuchen86/article/details/114007177