RestTemplate基础用法

在开发项目中,不可避免的需要调用某些第三方接口,我们可以使用Apache的HttpClient
请求框架。封装了常用的http的请求头,参数,内容体,响应等等。当然也可以使用HttpURLConnection
Java标准类,来完成一些第三方调用服务。
RestTemplate是Spring提供的同步请求Rest服务的客户端,简化了http服务的通信,支持RestFul原则。

查阅RestTemplate文档,RestTemplate是同步客户端执行HTTP请求,在基础
HTTP客户端库(如JDK HttpURLConnection,Apache HttpComponents等)上公开简单的模板方法API 。


官方文档:
https://docs.spring.io/spring-framework/docs/5.2.8.RELEASE/javadoc-api/org/springframework/web/client/RestTemplate.html
如何使用RestTemplate?(以下案例是基于SpringBoot开发)


1.在使用RestTemplate之前,我们需要对RestTemplate做一些初始化配置。

在构建RestTemplate我们可以通过ClientHttpRequestFactory指定使用不同的HTTP请求方式。

ClientHttpRequestFactory接口主要提供了两种实现方式:

1.SimpleClientHttpRequestFactory,使用J2SE提供的方式(既java.net包提供的方式)创建底层
的Http请求连接,RestTemplate默认是使用SimpleClientHttpRequestFactory,内部是调用jdk的
HttpConnection,默认超时为-1;

2.HttpComponentsClientHttpRequestFactory方式,底层使用HttpClient访问远程的Http服务,
使用HttpClient可以配置连接池和证书等信息。

1.SimpleClientHttpRequestFactory构建

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
        RestTemplate restTemplate = new RestTemplate(factory);
        return restTemplate;
    }

    @Bean
    public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setReadTimeout(5000); //请求超时时间
        factory.setConnectTimeout(5000);//连接超时时间
        //...
        return factory;
    }

}

 

2.HttpComponentsClientHttpRequestFactory 构建

依赖HttpClient包需要引入。
<dependency>
     <groupId>org.apache.httpcomponents</groupId>
     <artifactId>httpclient</artifactId>
     <version>4.5.6</version>
</dependency>
@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
        RestTemplate restTemplate = new RestTemplate(factory);
        return restTemplate;
    }

    @Bean
    public ClientHttpRequestFactory HttpComponentsClientHttpRequestFactory() {
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient());
        return factory;
    }

    public HttpClient httpClient() {
        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.getSocketFactory())
                .register("https", SSLConnectionSocketFactory.getSocketFactory())
                .build();
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
        //设置整个连接池最大连接数 根据自己的场景决定
        connectionManager.setMaxTotal(100);
        //路由是对maxTotal的细分
        connectionManager.setDefaultMaxPerRoute(100);
        RequestConfig requestConfig = RequestConfig.custom()
                //服务器返回数据(response)的时间,超过该时间抛出read timeout
                .setSocketTimeout(10000)
                //连接上服务器(握手成功)的时间,超出该时间抛出connect timeout
                .setConnectTimeout(5000)
                //从连接池中获取连接的超时时间,超过该时间未拿到可用连接,
                // 会抛出org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
                .setConnectionRequestTimeout(1000)
                .build();
        return HttpClientBuilder.create()
                .setDefaultRequestConfig(requestConfig)
                .setConnectionManager(connectionManager)
                .build();
    }
}
初始化配置RestTemplate完成后,下文会根据案例来说明如何具体使用RestTemplate。

Get请求案例

服务器端

@RestController
@RequestMapping("/api/rest")
public class TestRestTemplateController {

    @GetMapping("/get1/{id}/{name}")
    public JSONObject onGet1(@PathVariable("id") Integer id, @PathVariable("name") String name) {
        JSONObject object = new JSONObject();
        object.put("id", id);
        object.put("name", name);
        object.put("type", "get2");
        return ResultTool.successData(object);
    }

    @GetMapping("/get2")
    public JSONObject onGet2(@RequestParam(value = "id") Integer id, @RequestParam(value = "name") String name) {
        JSONObject object = new JSONObject();
        object.put("id", id);
        object.put("name", name);
        object.put("type", "get2");
        return ResultTool.successData(object);
    }
}
Get请求之getForObject。以JSON形式自动化转换responseType指定返回类型。


url:请求地址
responseType:返回值类型 结果转换后的对象
uriVariables:携带参数
public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables){}
public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables)
public <T> T getForObject(URI url, Class<T> responseType)


@Test
void get1() {
	String results = restTemplate.getForObject(BASE_URL + "/get1/1/张三", String.class);
	logger.info(results);
    输出:{"msg":"","code":200,"data":{"name":"张三","id":1,"type":"get2"}}
}

@Test
void get2() {
	JSONObject results = restTemplate.getForObject(BASE_URL + "/get1/{1}/{2}", JSONObject.class, "10086", "我的团长我的团");
	logger.info(results.getString("code"));
	logger.info(results.getString("data"));
	logger.info(results.getString("msg"));
    输出:...
}

@Test
void get3() {
	Map<String, String> map = new HashMap();
	map.put("id", "10001");
	map.put("name", "厉兵秣马");
	JSONObject results = restTemplate.getForObject(BASE_URL + "/get2?id={id}&name={name}", JSONObject.class, map);
	logger.info(results.getString("code"));
	logger.info(results.getString("data"));
	logger.info(results.getString("msg"));
    输出:...
}
   
Get请求之getForEntity。getForEntity()方法返回的是ResponseEntity对象,ResponseEntity对象
方便处理原生的response信息。

url:请求地址
responseType:返回值类型 结果转换后的对象
uriVariables:携带参数
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables){}
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables){}
public <T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType){}


@Test
void get1() {
	ResponseEntity<String> responseEntity = restTemplate.getForEntity(BASE_URL + "/get1/1/张三", String.class);
	logger.info(responseEntity.getStatusCode().toString());
	logger.info(responseEntity.getStatusCodeValue()+"");
	logger.info(responseEntity.getBody());
	responseEntity.getHeaders().forEach((v,k)->{
		logger.info("headerKey: "+v+"====="+"headerValue: "+k);
	});
}

@Test
void get2() {
	ResponseEntity<JSONObject> responseEntity = restTemplate.getForEntity(BASE_URL + "/get1/{1}/{2}", JSONObject.class, "10086", "我的团长我的团");
	JSONObject results = responseEntity.getBody();
	logger.info(results.getString("code"));
	logger.info(results.getString("data"));
	logger.info(results.getString("msg"));
}

@Test
void get3() {
	Map<String, String> map = new HashMap();
	map.put("id", "10001");
	map.put("name", "厉兵秣马");
	ResponseEntity<JSONObject> responseEntity = restTemplate.getForEntity(BASE_URL + "/get2?id={id}&name={name}", JSONObject.class, map);
	JSONObject results = responseEntity.getBody();
	logger.info(results.getString("code"));
	logger.info(results.getString("data"));
	logger.info(results.getString("msg"));
}

Post请求案例

@RestController
@RequestMapping("/api/rest")
public class TestRestTemplateController {

    //JSON
    @PostMapping("/post1")
    public JSONObject onPost1(@RequestBody  Test test) {
        return ResultTool.successData(test);
    }

    //form-data
    @PostMapping("/post2/form/data")
    public JSONObject onPost2(@RequestParam("id") Integer id,@RequestParam("name") String name) {
        JSONObject object = new JSONObject();
        object.put("id", id);
        object.put("name", name);
        object.put("type", "post2");
        return ResultTool.successData(object);
    }
}
POST之postForObject。

url:请求地址
request参数可以是aHttpEntity以便向请求中添加其他HTTP标头。
responseType:返回值类型 结果转换后的对象
uriVariables:动态URL
public <T> postForObject(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables)
public <T> postForObject(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables)
public <T> postForObject(URI url, @Nullable Object request, Class<T> responseType,  responseType)



@Test
void get1() {
	//设置请求头
	HttpHeaders headers = new HttpHeaders();
	headers.setContentType(MediaType.APPLICATION_JSON);
	//body参数
	Map<String, String> map = new HashMap<>();
	map.put("id", "1");
	map.put("name", "动次打次打次打");
	HttpEntity<Map<String, String>> httpEntity = new HttpEntity<>(map, headers);
	String result = restTemplate.postForObject(BASE_URL + "/post1", httpEntity, String.class);
	logger.info(result);
}

@Test
void get2() {
	//设置请求头
	HttpHeaders headers = new HttpHeaders();
	headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
	//body参数
	MultiValueMap<String, String> map= new LinkedMultiValueMap<>();
	map.add("id", "2");
	map.add("name", "红中红中");
	HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(map, headers);
	///{1}/{2}动态拼接请求地址
	JSONObject result = restTemplate.postForObject(BASE_URL + "/post2/{1}/{2}", httpEntity, JSONObject.class, "form", "data");
	logger.info(result.toJSONString());
}

@Test
void get3() {
	//设置请求头
	HttpHeaders headers = new HttpHeaders();
	headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
	//body参数
	MultiValueMap<String, String> map= new LinkedMultiValueMap<>();
	map.add("id", "3");
	map.add("name", "多热热水");
	HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(map, headers);
	//{one}/{two}动态拼接请求地址
	Map<String,String> mapUrl = new HashMap<>();
	mapUrl.put("one","form");
	mapUrl.put("two","data");
	JSONObject result = restTemplate.postForObject(BASE_URL + "/post2/{one}/{two}", httpEntity, JSONObject.class, mapUrl);
	logger.info(result.toJSONString());
}
POST之postForEntity。

url:请求地址
request参数可以是aHttpEntity以便向请求中添加其他HTTP标头。
responseType:返回值类型 结果转换后的对象
uriVariables:动态URL
public <T> ResponseEntity<T> postForEntity(String url, @Nullable Object request,Class<T> responseType, Object... uriVariables)
public <T> ResponseEntity<T> postForEntity(String url, @Nullable Object request,Class<T> responseType, Map<String, ?> uriVariables)
public <T> ResponseEntity<T> postForEntity(URI url, @Nullable Object request, Class<T> responseType)

案例省略...
exchange自定义请求方式
exchange()可以指定HttpMethod,请求体requestEntity。

@Test
void get1() {
	//设置请求头
	HttpHeaders headers = new HttpHeaders();
	headers.setContentType(MediaType.APPLICATION_JSON);
	//body参数
	Map<String, String> map = new HashMap<>();
	map.put("id", "1");
	map.put("name", "动次打次打次打");
	HttpEntity<Map<String, String>> httpEntity = new HttpEntity<>(map, headers);
	//exchange 自定义
	ResponseEntity<String> result = restTemplate.exchange(BASE_URL + "/post1", HttpMethod.POST, httpEntity, String.class);
	logger.info(result.getBody());
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值