RestTemplate较为通用的使用方法
一丶http请求响应
1. http请求主要包括3个部分, 请求行(get,post等请求方法 url地址 http协议版本), 请求头( key value形式), 请求体(任意文本, 通常与请求头content-type对应).

2. http响应主要包括3个部分, 响应消息行(协议/版本 响应状态码 对响应状态码的描述), 响应消息头(key value形式), 响应消息正文(任意文本, 通常与响应消息头content-type对应)


更详细的请看此博文
二丶restTemplate使用简述
处理http请求, 主要是构造生成http请求报文, 处理转换http响应报文.
在实际项目中, 主要是使用get, post两种请求.
1) get请求, 主要是在请求行中的url带上请求参数, 如http://localhost:8080/server/userId?userId=2 中的userId=2, url路径中的部分数据也可以作为请求参数, 如http://localhost:8080/server/userId/2中的2, 可以和前一个url等同
restTemplate主要是通过占位符{}来构造url,
#getForObject(url, responseType, uriVariables), #getForEntity(url, responseType, uriVariables) 等方法用于get请求,
其中responseType指定了反序列化响应体后的类型, url, uriVariables 用于构造请求url, getForEntity可以得到响应码等状态信息

2) post请求, 主要是在请求体中带上自定义的数据, 通常为json, 在使用时, 通常需要在请求头指定请求体的内容类型, json内容类型为 "Content-Type: application/json"
请求头:对应于org.springframework.http.HttpHeaders
请求体:对应于org.springframework.http.HttpEntity#body属性
请求头和请求体 对应于org.springframework.http.HttpEntity
#postForObject(String url, Object request, Class<T> responseType,Object... uriVariables)
#postForEntity(String url, Object request,Class<T> responseType, Object... uriVariables) 等用于Post方法
3) resttemplate较为自由的执行方法
#exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType, Map<String, ?> uriVariables)
可以自定义httpmethod, url,请求头,q请求体,响应类型
4) 简单总结
使用restTemaplate主要围绕http报文来使用, 基本熟悉了http报文的结构, 以及resttemaplate的实现思想, 就可以很好的使用resttemplate了
三丶使用样例
@Component
@Slf4j
public class RestTemplateManager {
@Autowired
private RestTemplateConfig config;
private RestTemplate restTemplate;
private String SERVER_PREFIX;
@PostConstruct
public void init(){
restTemplate=new RestTemplate();
//使用fastjson转换json
restTemplate.getMessageConverters().add(0, new FastJsonHttpMessageConverter());
//打印调试日志
restTemplate.setInterceptors(Arrays.asList(new LoggingRequestInterceptor()));
SERVER_PREFIX=config.getUrl();
}
/**
* get请求
* @param requestDto
*/
public GetExampleDataDto getExample(GetExampleRequestDto requestDto){
String url=SERVER_PREFIX+"/get-example?userId={userId}&age={age}";
try{
//请求参数
Map vars=(JSONObject)JSON.toJSON(requestDto);
ResponseEntity<String> entity=restTemplate.getForEntity(url, String.class, vars);
Assert.state(entity.getStatusCode()==HttpStatus.OK, "状态码不等于200");
GetExampleDataDto dataDto=getData(entity.getBody(), GetExampleDataDto.class);
return dataDto;
}catch (Exception e){
String message="请求url: "+url+"出错";
log.error(message, e);
log.error("请求参数: {}", JSON.toJSON(requestDto));
throw new RuntimeException(message, e);
}
}
/**
* get请求, 带上请求头
* @param requestDto
* @param token 登录token
*/
public GetExampleDataDto getExampleWithHeader(GetExampleRequestDto requestDto, String token){
String url=SERVER_PREFIX+"/get-example?userId={userId}&age={age}";
try{
//请求参数
Map vars=(JSONObject)JSON.toJSON(requestDto);
//一般在请求头的cookie带上登录token
HttpCookie tokenCookie=new HttpCookie("token", token);
HttpHeaders headers=new HttpHeaders();
headers.add(HttpHeaders.COOKIE, tokenCookie.toString());
HttpEntity requestEntity=new HttpEntity(headers);
ResponseEntity<String> entity=restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class, vars);
Assert.state(entity.getStatusCode()==HttpStatus.OK, "状态码不等于200");
GetExampleDataDto dataDto=getData(entity.getBody(), GetExampleDataDto.class);
return dataDto;
}catch (Exception e){
String message="请求url: "+url+"出错";
log.error(message, e);
log.error("请求参数: {}", JSON.toJSON(requestDto));
throw new RuntimeException(message, e);
}
}
/**
* post请求
* @param requestDto
*/
public PostExampleDataDto postExample(PostExampleRequestDto requestDto){
String url=SERVER_PREFIX+"/post-example";
try{
//请求参数
HttpEntity httpEntity=new HttpEntity(requestDto, createJsonHeader());
ResponseEntity<String> entity=restTemplate.postForEntity(url, httpEntity, String.class);
Assert.state(entity.getStatusCode()==HttpStatus.OK, "状态码不等于200");
PostExampleDataDto dataDto=getData(entity.getBody(), PostExampleDataDto.class);
return dataDto;
}catch (Exception e){
String message="请求url: "+url+"出错";
log.error(message, e);
log.error("请求参数: {}", JSON.toJSON(requestDto));
throw new RuntimeException(message, e);
}
}
private HttpHeaders createJsonHeader(){
HttpHeaders headers=new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return headers;
}
private <T> T getData(String responseString, Class<T> clazz){
StringDataResponseDto responseDto=JSONObject.parseObject(responseString)
.toJavaObject(StringDataResponseDto.class);
if(responseDto.getCode()!=0){
throw new RuntimeException("code不等于0, 值为["+responseDto.getCode()+"]," +
" message=["+responseDto.getMessage()+"]");
}
String stringData=responseDto.getData();
return JSONObject.parseObject(stringData).toJavaObject(clazz);
}
@Data
private static class StringDataResponseDto extends ResponseDto<String> {
}
}
四丶单元测试
主要是使用mockserver来模拟请求服务器 ^_^ 非常好的工具
<dependency>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-netty</artifactId>
<version>5.8.1</version>
<scope>test</scope>
</dependency>
/**
* https://github.com/mock-server/mockserver/tree/master/mockserver-examples
*
* https://github.com/mock-server/mockserver/blob/master/mockserver-examples/src/main/java/org/mockserver/examples/mockserver/MockServerClientExamples.java
*
* @author TimFruit
* @date 19-12-30 下午7:54
*/
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("unittest")
public class ResttemplateManagerTests {
private int port=8055;
@Rule
public MockServerRule mockServerRule = new MockServerRule(this, port);
private MockServerClient client=new MockServerClient("localhost", port);
private String prefixurl="/mockserver";
@Autowired
RestTemplateManager templateManager;
/*
public void createExpectationMockServerClient() {
new MockServerClient("localhost", 1080)
.when(
request()
.withMethod("GET")
.withPath("/view/cart")
.withCookies(
cookie("session", "4930456C-C718-476F-971F-CB8E047AB349")
)
.withQueryStringParameters(
param("cartId", "055CA455-1DF7-45BB-8535-4F83E7266092")
)
)
.respond(
response()
.withBody("some_response_body")
);
}
*/
@Test
public void shouldGet() throws IOException {
//given
String expectedResponseBody=FileUtils.readContent("httpmanager/get-example-response.json");
client.when(
request().withMethod("GET").withPath(prefixurl+"/get-example")
.withQueryStringParameters(
param("userId", "1"), param("age", "1")
)
).respond(
response().withContentType(MediaType.APPLICATION_JSON)
//mock 结果来验证
.withBody(expectedResponseBody)
);
//when
GetExampleRequestDto requestDto=new GetExampleRequestDto();
requestDto.setUserId(1);
requestDto.setAge(1);
GetExampleDataDto dataDto=templateManager.getExample(requestDto);
//then
Assert.assertEquals(5, dataDto.getUserId().intValue());
Assert.assertEquals(99, dataDto.getAge().intValue());
}
@Test
public void shouldGetWithHeader() throws IOException {
//given
String token="timfruit2019";
String expectedResponseBody=FileUtils.readContent("httpmanager/get-example-response.json");
client.when(
request().withMethod("GET").withPath(prefixurl+"/get-example")
.withQueryStringParameters(
param("userId", "1"), param("age", "1")
)
//header-cookie
.withCookie("token", token)
).respond(
response().withContentType(MediaType.APPLICATION_JSON)
//mock 结果来验证
.withBody(expectedResponseBody)
);
//when
GetExampleRequestDto requestDto=new GetExampleRequestDto();
requestDto.setUserId(1);
requestDto.setAge(1);
GetExampleDataDto dataDto=templateManager.getExampleWithHeader(requestDto, token);
//then
Assert.assertEquals(5, dataDto.getUserId().intValue());
Assert.assertEquals(99, dataDto.getAge().intValue());
}
@Test
public void shouldPost(){
//given
String expectedRequestBody=FileUtils.readContent("httpmanager/post-example-request.json");
String expectedResponseBody=FileUtils.readContent("httpmanager/post-example-response.json");
client.when(
request().withMethod("POST").withPath(prefixurl+"/post-example")
.withContentType(MediaType.APPLICATION_JSON)
.withBody(new JsonBody(expectedRequestBody))
).respond(
response().withContentType(MediaType.APPLICATION_JSON)
//mock 结果来验证
.withBody(expectedResponseBody)
);
//when
PostExampleRequestDto requestDto=new PostExampleRequestDto();
requestDto.setUserId(5);
requestDto.setBookIds(Arrays.asList(1, 2 , 3, 4));
PostExampleDataDto dataDto=templateManager.postExample(requestDto);
//then
Assert.assertEquals(5, dataDto.getUserId().intValue());
Assert.assertEquals(4, dataDto.getBookIdCount().intValue());
}
}
学习资料:
来源:https://www.cnblogs.com/timfruit/p/12124315.html