使用Spring RestTemplate访问Rest服务

简介

RestTemplate是Spring3.0后开始提供的用于访问 Rest 服务的轻量级客户端,相较于传统的HttpURLConnection、Apache HttpClient、OkHttp等框架,RestTemplate大大简化了发起HTTP请求以及处理响应的过程。

RestTemplate只是对其它Rest客户端的一个封装,本身并没有自己的实现。
很多人都说Spring Boot 2.0之前RestTestTemplate的默认实现是HttpClient,2.+为OKHttp3,其实这种说法并不完全正确,如果没有引入这些客户端的jar包,其默认实现是HttpURLConnection(集成了URLConnection),这是JDK自带的REST客户端实现。

引入依赖:

 
 
 1 <dependency>
 2     <groupId>org.projectlombok</groupId>
 3     <artifactId>lombok</artifactId>
 4     <version>1.16.18</version>
 5     <scope>provided</scope>
 6 </dependency>
 7 
 8 <dependency>
 9     <groupId>com.squareup.okhttp3</groupId>
10     <artifactId>okhttp</artifactId>
11     <version>3.11.0</version>
12 </dependency>

 

引入RestTemplate

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

/**
 * RestTemplate配置类
 */
@Configuration
public class RestTemplateConfig {

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

    @Bean
    public OkHttp3ClientHttpRequestFactory okHttp3ClientHttpRequestFactory(){
        OkHttp3ClientHttpRequestFactory factory = new OkHttp3ClientHttpRequestFactory();
        // 单位:毫秒
        factory.setConnectTimeout(10000);
        factory.setReadTimeout(10000);
        factory.setWriteTimeout(10000);
        return factory;
    }
}

注入RestTemplate

@Autowired
private RestTemplate restTemplate;

测试准备

新建User对象,用于下面不同请求方式的测试。
构建Http服务。

import lombok.Data;
@Data
public class User {
    private Long id;
    private String username;
    private Integer age;
}

import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/")
@Slf4j
public class DemoController {

    @GetMapping("demo/{id}/{userName}")
    public User get(@PathVariable Long id, @PathVariable String userName, Integer age){
        log.info("id:{}, userName:{}, age:{}", id, userName, age);
        User user = new User();
        user.setId(id);
        user.setUsername(userName);
        user.setAge(age);
        return user;
    }

    @PostMapping("demo")
    public User post(@RequestBody String json){
        log.info("json:{}", json);
        Gson gson = new Gson();
        User user = gson.fromJson(json, User.class);
        return user;
    }
}

GET请求

GET请求对应两个方法,getForObject()和getForEntity(),每个方法又对应有具体的三个重载方法。这两者的区别在于getForObject()返回的是一个简单的对象,而getForEntity()响应的数据中,还额外包含有与HTTP相关的信息,如响应码、响应头等。

//URL中的{id}占位符最终将会用方法的id参数来填充
String url = "http://127.0.0.1:8083/demo/{id}/{userName}?age=18";
Long id = 1001L;
String userName = "Tom";

//重载1:最后一个参数是大小可变的参数列表,每个参数都会按出现顺序插入到指定URL的占位符中
User user = restTemplate.getForObject(url, User.class, id, userName);
System.out.println("user = " + user);

//重载2:将id参数放到Map中,并以id作为key,然后将这个Map作为最后一个参数
Map<String, Object> urlParams = new HashMap<>();
urlParams.put("id", id);
urlParams.put("userName", userName);
User user2 = restTemplate.getForObject(url, User.class, urlParams);
System.out.println("user2 = " + user2);

//重载1:同getForObject(),只不过返回的类型是ResponseEntity
ResponseEntity<User> userResponseEntity = restTemplate.getForEntity(url, User.class, id, userName);
User user3 = userResponseEntity.getBody();
HttpStatus statusCode = userResponseEntity.getStatusCode();
int statusCodeValue = userResponseEntity.getStatusCodeValue();
HttpHeaders headers = userResponseEntity.getHeaders();
System.out.println("user = " + user3 + "; statusCode = " + statusCode + "; statusCodeValue = " + statusCodeValue + "; headers = " + headers);

//重载1:同getForObject(),只不过返回的类型是ResponseEntity
Map<String, Object> urlParams2 = new HashMap<>(1);
urlParams2.put("id", id);
urlParams2.put("userName", userName);
ResponseEntity<User> userResponseEntity2 = restTemplate.getForEntity(url, User.class, urlParams2);
System.out.println("userResponseEntity2 = " + userResponseEntity2);

POST请求

POST请求对应三个方法,postForObject()、postForEntity()和postForLocation(),每个方法同样对应有三个具体的重载方法。postForObject()、postForEntity()类似于getForObject()和postForEntity(),postForLocation()返回的是一个URI对象。

String url = "http://localhost:8083/demo2";
//重载1 & 重载2
User user1 = new User();
user1.setId(12L);
user1.setAge(20);
user1.setUsername("张三");
//第4个参数可以是Object... uriVariables 或者 Map<String, ?> uriVariables
User u1 = restTemplate.postForObject(url, user1, User.class);
System.out.println("user1 = " + u1);
//重载3
User user2 = new User();
user2.setId(12L);
user2.setAge(30);
user2.setUsername("李四");
User u2 = restTemplate.postForObject(URI.create(url), user2, User.class);
System.out.println("user2 = " + u2);
// 重载1 & 重载2
User user3 = new User();
user3.setAge(25);
user3.setUsername("王五");
// 第4个参数可以是Object... uriVariables 或者 Map<String, ?> uriVariables
ResponseEntity<User> userResponseEntity = restTemplate.postForEntity(url, user3, User.class);
User userBody = userResponseEntity.getBody();
HttpStatus statusCode = userResponseEntity.getStatusCode();
int statusCodeValue = userResponseEntity.getStatusCodeValue();
HttpHeaders headers = userResponseEntity.getHeaders();
System.out.println("user = " + userBody + "; statusCode = " + statusCode + "; statusCodeValue = " + statusCodeValue + "; headers = " + headers);
// 重载3
User user4 = new User();
user4.setAge(35);
user4.setUsername("陆六");
ResponseEntity<User> userResponseEntity2 = restTemplate.postForEntity(URI.create(url), user4, User.class);
System.out.println("userResponseEntity2 = " + userResponseEntity2);

exchange通用请求

建议大家多使用exchange()。

String getUrl = "http://127.0.0.1:8083/demo/{id}/{userName}?age=18";

//GET资源
//参数3是请求头部分;参数4是响应数据要转成对象;最后一个参数用于替换URL中的占位符
ResponseEntity<User> userResponseEntity = restTemplate.exchange(getUrl, HttpMethod.GET, null, User.class, 1001L, "Tom");
System.out.println("exchange = " + userResponseEntity + "; response body = " + userResponseEntity.getBody());

String postUrl = "http://localhost:8083/demo2";

//POST资源
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
String jsonParams = "{\"username\":\"123\",\"age\":23}";
HttpEntity<User> httpEntity = new HttpEntity(jsonParams, headers);
ResponseEntity<User> responseEntity = restTemplate.exchange(postUrl, HttpMethod.POST, httpEntity, User.class);
System.out.println("exchange = " + responseEntity + "; response body = " + responseEntity.getBody());

POST请求,from-data传参

String url = "http://localhost:8083/demo2";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
MultiValueMap map = new LinkedMultiValueMap();
map.add("id",1001L);
HttpEntity requestBody = new HttpEntity(map, headers);
ResponseEntity<User> responseEntity = restTemplate.postForEntity(url, requestBody, User.class);
System.out.println(responseEntity.getBody());
Markdown 6340 字数 209 行数 当前行 1, 当前列 0
HTML 6165 字数 167 段落
posted @ 2019-08-09 17:47  const-  阅读(224)  评论(0编辑  收藏  举报