HttpClient和RestTemplate的使用(详细对比)

it2025-05-14  9

文章目录

HttpClient和RestTemplate的使用(详细对比)一、HttpClient1. get 无参2. get 带参3. post 对象4.关闭控制台日志 二、RestTemplate1.使用方法1)发起请求2)添加超时时间3)添加headers4)restful 风格 url参数5)添加get参数6)添加post请求体7)调用第三方接口 2.使用案例1)get 无参2)get @PathVariable3)☆ get headers @PathVariable @RequestParam4)post @RequestParam5)post @RequestBody6)☆ post @RequestParam @RequsetBody

HttpClient和RestTemplate的使用(详细对比)

今天分到的接口中,有几个需要调用第三方的接口数据,一窍不通的我,从零开始

一、HttpClient

首先导入依赖

<!-- 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 无参

@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(); } } }

打印输出:

2. get 带参

请求地址 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(); } } }

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

打印输出:

3. post 对象

@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(); } } }

请求接口:

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

打印输出:

4.关闭控制台日志

resource 下创建 logback.xml

<?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>

二、RestTemplate

1.使用方法

1)发起请求

get请求

getForObject() 发送一个HTTP GET请求,返回的请求体将映射为一个对象

getForEntity() 发送一个HTTP GET请求,返回的ResponseEntity包含了响应体所映射成的对象

RestTemplate restTemplate = new RestTemplate(); ResponseEntity<String> entity = restTemplate.getForEntity(uri, String.class); // TODO 处理响应 Post请求方式

postForEntity() POST 数据到一个URL,返回包含一个对象的ResponseEntity,这个对象是从响应体中映射得到的。

postForObject() POST 数据到一个URL,返回根据响应体匹配形成的对象。

postForLocation() POST 数据到一个URL,返回新创建资源的URL

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)添加超时时间

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

3)添加headers

只有post请求有header参数,get可以用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 风格 url参数

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)添加get参数

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)添加post请求体

// 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)调用第三方接口

//调用第三方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... }

不同Spring版本的默认字符编码不一样

spring-framework.version 5.2.9

spring-framework.version 4.3.9

2.使用案例

1)get 无参

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

打印输出

{查询成功: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); }

打印输出:

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

请求接口:

@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

get请求没有headers,用exchange替代

/** * 畅捷通接口说明 应收统计表 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; }

打印输出:

执行结果: 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()); }

打印输出:

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

请求地址:

@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()); }

打印输出:

查询成功

请求接口:

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

打印输出:

返回结果: 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 ===============================================
最新回复(0)