Java SpringBoot

基于 Springboot 2.3.12.RELEASE 版本测试


RestTemplate 是 Spring 官方提供的一个同步的 Web Http 客户端请求模板工具。

其他常用客户端工具有:JDK HttpUrlConnection、Apache HttpClient、OkHttp 等。

Spring 的 RestTemplate 默认使用 HttpUrlConnection 提供发送 HTTP 请求的支持,可以指定相关工厂类更换请求工具。

例:使用 Apache HttpClient

RestTemplate template = new RestTemplate(new HttpComponentsClientHttpRequestFactory());


在使用 RestTemplate 工具前进行注入

@Bean
public RestTemplate restTemplate() {
    // RestTemplate 默认使用 HttpUrlConnection。
    return new RestTemplate();
}

controller 样例:

@RequestMapping("/demo")
@RestController
public class DemoController {...}

单元测试类:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = DemoApp.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class DemoControllerTest {
    public static final String URL = "http://localhost:18080/rest-demo";
    
    @Autowired
    private RestTemplate restTemplate;
}


发送 GET 请求

使用 getForObject 方法发送 GET 请求

既然是 REST 风格,请求参数一般都组合为一个URI

@GetMapping("/getById1/{id}")
public UserInfo getById1(@PathVariable("id") Long id) { ... }

发送请求代码

UserInfo userInfo = restTemplate.getForObject(URL + "/demo/getById1/2", UserInfo.class);

可以通过第二个参数指定返回类型,RestTemplate 是通过 JSON 解析返回结果的,也可以使用 Map 接收。



如果使用 @RequestParam 接收参数,需要使用 ? 拼接URL地址。

@GetMapping("/getById2")
public UserInfo getById2(@RequestParam("id") Long id) { ... }

发送请求代码

UserInfo userInfo = restTemplate.getForObject(URL + "/demo/getById2?id=10", UserInfo.class);


使用 getForEntity 方法发送 GET 请求

getForEntity() 方法和 getForObject() 方法使用类似,不同的是请求返回结果封装在 ResponseEntity 对象中,通过该对象可以获取更多网络响应信息。

ResponseEntity<UserInfo> forEntity 
        = restTemplate.getForEntity(URL + "/demo/getById1/2", UserInfo.class);

HttpStatus statusCode = forEntity.getStatusCode();
int statusCodeValue = forEntity.getStatusCodeValue();
HttpHeaders headers = forEntity.getHeaders();
UserInfo body = forEntity.getBody();


使用 exchange 方法发送 GET 请求

exchange() 方法即可以发送任意其他网络请求,发送 GET 和 POST 等其他方法底层使用的也是该方法。

exchange() 方法返回的结果也都封装在 ResponseEntity 对象中。

ResponseEntity<UserInfo> exchange
        = restTemplate.exchange(URL + "/demo/getById1/30", HttpMethod.GET, null, UserInfo.class);

HttpStatus statusCode = exchange.getStatusCode();
int statusCodeValue = exchange.getStatusCodeValue();
HttpHeaders headers = exchange.getHeaders();
UserInfo body = exchange.getBody();


发送 POST 请求

使用 getForObject 方法发送 POST 请求

1、发送 POST 请求参数需要使用 MultiValueMap 对象,使用自定义类型 UserInfo 是无法接收到参数的。

@PostMapping("/add1")
public UserInfo addUser1(Long id, String name) { ... }

发送请求样例:

MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
params.add("id", 20L);
params.add("name", "Post");

UserInfo userInfo 
        = restTemplate.postForObject(URL + "/demo/add1", params, UserInfo.class);

即使是使用自定义对象 UserInfo 接收参数,在发送请求时依然需要使用 MultiValueMap 对象。

@PostMapping("/add2")
public UserInfo addUser2(UserInfo userInfo) { ... }


2、如果接收参数时使用了 @RequestBody 注解:

@PostMapping("/add3")
public UserInfo addUser3(@RequestBody UserInfo userInfo) { ... }

则在发送请求时需要使用自定义对象,使用 MultiValueMap 对象封装参数会出现 500 异常。

UserInfo params = new UserInfo();
params.setId(10L);
params.setName("Post");

UserInfo userInfo = restTemplate.postForObject(URL + "/demo/add3", params, UserInfo.class);


3、将发送请求的参数封装到 HttpEntity 对象中可以设置请求头

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

UserInfo params = new UserInfo();
params.setId(20L);
params.setName("Post");

HttpEntity<UserInfo> httpEntity = new HttpEntity<>(params, headers);

UserInfo userInfo = restTemplate.postForObject(URL + "/demo/add3", httpEntity, UserInfo.class);


使用 getForEntity 方法发送 POST 请求

postForEntity() 方法和 postForObject() 方法类似,只是放回结果封装到了 ResponseEntity 对象中。

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

UserInfo params = new UserInfo();
params.setId(20L);
params.setName("Post");

HttpEntity<UserInfo> httpEntity = new HttpEntity<>(params, headers);

ResponseEntity<UserInfo> responseEntity = restTemplate.postForEntity(URL + "/demo/add3", httpEntity, UserInfo.class);

HttpStatus statusCode = responseEntity.getStatusCode();
int statusCodeValue = responseEntity.getStatusCodeValue();
HttpHeaders responseEntityHeaders = responseEntity.getHeaders();
UserInfo body = responseEntity.getBody();

这里请求参数使用了 HttpEntity 对象进行了封装,也可以不使用。


使用 exchange 方法发送 POST 请求

使用 exchange() 方法发送请求,请求参数必须使用 HttpEntity 对象进行封装,返回结果也封装在 ResponseEntity 对象中:

UserInfo params = new UserInfo();
params.setId(20L);
params.setName("Post");

HttpEntity<UserInfo> httpEntity = new HttpEntity<>(params);

ResponseEntity<UserInfo> exchange 
	= restTemplate.exchange(URL + "/demo/add3", HttpMethod.POST, httpEntity, UserInfo.class);


Http 协议的状态码分类

1xx 通知

2xx 请求成功

3xx 重定向 

4xx 客户端异常

5xx 服务端异常



转载请指明出处!http://www.miselehe.com/article/view/37