Spring-RestTemplate使用方法(入门)
转载请注明出处
1.目录
3.构建RestTemplate对象并交给Spring容器管理
3.1 通过构造方法创建RestTemplate对象(适用于非Springboot环境)
3.2 通过注入RestTemplateBuilder对象的方式构建RestTemplate
4.2 无参Get请求(此处使用getForEntity方法,之后为方便阅读,使用forObject方法)
2.项目依赖
2.1 jdk及springboot版本
jdk8
spring-boot-starter-parent 2.5.3
2.2 配置文件准备
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
2.3 基础类
2.3.1 响应封装类BaseResult
/**
* 基础响应封装类
*
* @param <T>
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class BaseResult<T> implements Serializable {
private String code;
private String message;
private T data;
public BaseResult(ResultCode resultCode, T data) {
this.code = resultCode.getCode();
this.message = resultCode.getMessage();
this.data = data;
}
private static final BaseResult<Object> DEFAULT_SUCCESS_RESULT = new BaseResult<>(ResultCode.SUCCESS, null);
public static <T> BaseResult<T> create(String code, String msg, T data) {
return new BaseResult<>(code, msg, data);
}
public static <T> BaseResult<T> create(ResultCode resultCode, T data) {
return new BaseResult<>(resultCode.getCode(), resultCode.getMessage(), data);
}
public static <T> BaseResult<T> success(T data) {
return create(ResultCode.SUCCESS, data);
}
public static <T> BaseResult<T> success() {
return success(null);
}
public static <T> BaseResult<T> fail(String code, String msg, T data) {
return create(code, msg, data);
}
public static <T> BaseResult<T> fail(ResultCode resultCode, T data) {
return create(resultCode, data);
}
public static <T> BaseResult<T> fail(String code, String msg) {
return create(code, msg, null);
}
public static <T> BaseResult<T> fail(ResultCode resultCode) {
return create(resultCode, null);
}
}
2.3.2 响应状态码ResultCode
/**
* 响应状态码及描述基础类
*/
@Getter
@AllArgsConstructor
public enum ResultCode {
SUCCESS("200", "成功"),
ERROR("500", "系统异常"),
;
final String code;
final String message;
}
2.3.3 教师类Teacher(RequestBody)
/**
* 老师类,用于测试post请求
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Teacher implements Serializable {
/**
* 姓名
*/
private String name;
/**
* 年龄
*/
private Integer age;
/**
* 住址
*/
private String addr;
/**
* 学生姓名集合
*/
private List<String> students;
/**
* 课程表{key:星期几,value:课程名称}
*/
private Map<String, String> projectTable;
}
3.构建RestTemplate对象并交给Spring容器管理
3.1 通过构造方法创建RestTemplate对象(适用于非Springboot环境)
@Component
public class RestTemplateConfig {
/**
* 通过构造方法创建RestTemplate对象
*
* @return
*/
@Bean("simpleRestTemplate")
public RestTemplate simpleRestTemplate() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(10_000);
factory.setConnectTimeout(10_000);
return new RestTemplate(factory);
}
}
3.2 通过注入RestTemplateBuilder对象的方式构建RestTemplate
/**
* restTemplate配置类
*/
@Component
public class RestTemplateConfig {
/**
* 默认restTemplate对象
*
* @param builder
* @return
*/
@Bean("defaultRestTemplate")
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder
.setConnectTimeout(Duration.ofSeconds(10))
.setReadTimeout(Duration.ofSeconds(10))
.build();
}
/**
* 带有默认header的restTemplate对象
*
* @param builder
* @return
*/
@Bean("templateWithDefaultHeaders")
public RestTemplate templateWithDefaultHeaders(RestTemplateBuilder builder) {
return builder
.setConnectTimeout(Duration.ofSeconds(10))
.setReadTimeout(Duration.ofSeconds(10))
.defaultHeader("default_header1", "I'm default header1")
.defaultHeader("default_header2", "I'm default header2")
.build();
}
}
3.3 RestTemplate发送请求的基本方法介绍
RestTemplate发送get和post请求的方法大致分为三类forEntity,forObject,forLocation
1.postForLocation方法本篇暂不讲解
2.forEntity方法返回完整的响应,包括响应头响应体等
3.forObject方法只返回响应体,无法获取响应头内容
<T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables) throws RestClientException {
<T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException {
<T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType) throws RestClientException {
<T> T getForObject(String url, Class<T> responseType, Object... uriVariables) throws RestClientException {
<T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException {
<T> T getForObject(URI url, Class<T> responseType) throws RestClientException {
URI postForLocation(String url, @Nullable Object request, Object... uriVariables) throws RestClientException {
URI postForLocation(String url, @Nullable Object request, Map<String, ?> uriVariables) throws RestClientException {
URI postForLocation(URI url, @Nullable Object request) throws RestClientException {
<T> ResponseEntity<T> postForEntity(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables) throws RestClientException {
<T> ResponseEntity<T> postForEntity(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException {
<T> ResponseEntity<T> postForEntity(URI url, @Nullable Object request, Class<T> responseType) throws RestClientException {
<T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables) throws RestClientException {
<T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException {
<T> T postForObject(URI url, @Nullable Object request, Class<T> responseType) throws RestClientException {
4.发送Get请求
4.1 接收Get请求的处理器类
/**
* 用于处理get请求的Controller
*/
@RestController
@RequestMapping("/httpGetController")
public class HttpGetController {
/**
* 无参get请求
*
* @return
*/
@GetMapping("/get")
public BaseResult<Object> get() {
return BaseResult.success();
}
/**
* 有参get请求
*
* @param name
* @param age
* @return
*/
@GetMapping("/getWithParams")
public BaseResult<Object> getWithParams(@RequestParam("name") String name, @RequestParam("age") Integer age) {
HashMap<String, Object> resultMap = new HashMap<>();
resultMap.put("name", name);
resultMap.put("age", age);
return BaseResult.success(resultMap);
}
}
4.2 无参Get请求(此处使用getForEntity方法,之后为方便阅读,使用forObject方法)
@Resource
private RestTemplate defaultRestTemplate;
/**
* 无参get请求
* getForEntity方法可以返回完整的响应,包括响应头和响应体
*/
@Test
void getForEntity() {
ResponseEntity<String> responseEntity = defaultRestTemplate.getForEntity("http://localhost:8080/httpGetController/get", String.class);
HttpHeaders headers = responseEntity.getHeaders();
String body = responseEntity.getBody();
log.info("响应体:{}", body);//响应体:{"code":"200","message":"成功","data":null}
headers.forEach((name, value) -> {
log.info("{}:{}", name, value);
//Content-Type:[application/json]
//Transfer-Encoding:[chunked]
//Date:[Wed, 28 Jul 2021 05:54:36 GMT]
//Keep-Alive:[timeout=60]
//Connection:[keep-alive]
});
}
4.3 有参Get请求(三种参数传递方式)
1.直接拼接url
/**
* 有参get请求
*/
@Test
@SneakyThrows
void getWithParams1() {
String url = "http://localhost:8080/httpGetController/getWithParams?name=张三&age=23";
String response = defaultRestTemplate.getForObject(url, String.class);
log.info(response);//{"code":"200","message":"成功","data":{"name":"张三","age":23}}
}
2.占位符+可变参数
/**
* 有参get请求
*/
@Test
@SneakyThrows
void getWithParams2() {
String url = "http://localhost:8080/httpGetController/getWithParams?name={0}&age={1}";
String response = defaultRestTemplate.getForObject(url, String.class, "张三", 23);
log.info(response);//{"code":"200","message":"成功","data":{"name":"张三","age":23}}
}
3.占位符+参数Map(占位符{}内部的变量需要与map中的key对应)
/**
* 有参get请求
*/
@Test
@SneakyThrows
void getWithParams3() {
String url = "http://localhost:8080/httpGetController/getWithParams?name={name}&age={age}";
Map<String, Object> params = new HashMap<>();
params.put("name", "张三");
params.put("age", 23);
String response = defaultRestTemplate.getForObject(url, String.class, params);
log.info(response);//{"code":"200","message":"成功","data":{"name":"张三","age":23}}
}
4. 上述3种参数传递方式也适用于post请求
5.发送Post请求(With Header Demo)
5.1 接收Post请求的处理器类
/**
* 用于处理post请求的Controller
*/
@Slf4j
@RestController
@RequestMapping("/httpPostController")
public class HttpPostController {
/**
* 无参post请求
*
* @return
*/
@PostMapping("/post")
public BaseResult<Object> post() {
return BaseResult.success("这是无参post请求");
}
/**
* post请求,参数为url参数
*
* @param name
* @param age
* @return
*/
@PostMapping("/postWithPathParams")
public BaseResult<Object> postWithPathParams(@RequestParam(value = "name", required = false) String name, @RequestParam(value = "age", required = false) Integer age) {
HashMap<String, Object> resultMap = new HashMap<>();
resultMap.put("name", name);
resultMap.put("age", age);
return BaseResult.success(resultMap);
}
/**
* post请求,参数为Teacher对象
*
* @param teacher
* @return
*/
@PostMapping("/postWithRequestBody")
public BaseResult<Teacher> postWithPathParams(@RequestBody Teacher teacher,
@RequestParam(value = "name", required = false) String name,
@RequestParam(value = "age", required = false) Integer age,
@RequestHeader(value = "default_header1", required = false) String header1,
@RequestHeader(value = "default_header2", required = false) String header2,
@RequestHeader(value = "temp_header1", required = false) String header3,
@RequestHeader(value = "temp_header2", required = false) String header4) {
log.info("\r\nheaders>>" +
"\r\ndefault_header1:{}," +
"\r\ndefault_header2:{}," +
"\r\ntemp_header1:{}," +
"\r\ntemp_header2:{}",
header1, header2, header3, header4);
log.info("\r\nparams>>" +
"\r\nname:{}" +
"\r\nage:{}",
name, age);
return BaseResult.success(teacher);
}
}
5.2 无参Post请求
@Resource
private RestTemplate defaultRestTemplate;
/**
* 无参post请求
*/
@Test
void postWithoutParams() {
String response = defaultRestTemplate.postForObject("http://localhost:8080/httpPostController/post", null, String.class);
log.info(response);//{"code":"200","message":"成功","data":"这是无参post请求"}
}
5.3 有参Post请求,附带两种增加Header的方法
1使用带有默认Header的RestTemplate对象发送请求
@Resource
private RestTemplate templateWithDefaultHeaders;
/**
* 有参post请求(requestBody)
* 使用带有默认Header的restTemplate对象发送http请求
*/
@Test
void postWithBodyAndDefaultHeader() {
Teacher teacher = getTeacher();
String response = templateWithDefaultHeaders.postForObject("http://localhost:8080/httpPostController/postWithRequestBody", teacher, String.class);
//这里将JSONString转成带有泛型的实体类,需要创建TypeReference对象
BaseResult<Teacher> baseResult = JSONObject.parseObject(response, new TypeReference<BaseResult<Teacher>>() {
});
log.info(baseResult != null ? baseResult.toString() : null);//BaseResult(code=200, message=成功, data=Teacher(name=李四, age=24, addr=北京, students=[张三, 王五], projectTable={Tus=语文, Mon=数学}))
}
public static Teacher getTeacher() {
Teacher teacher = new Teacher();
teacher.setName("李四");
teacher.setAge(24);
teacher.setAddr("北京");
teacher.setStudents(Lists.list("张三", "王五"));
Map<String, String> map = new HashMap<>();
map.put("Mon", "数学");
map.put("Tus", "语文");
teacher.setProjectTable(map);
return teacher;
}
2.请求之前创建新的Header
/**
* 有参post请求(requestBody)
* 创建临时的Header对象
*/
@Test
void postWithBodyAndHeader() {
Teacher teacher = getTeacher();
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add("temp_header1", "I'm temp header1");
headers.add("temp_header2", "I'm temp header2");
String response = defaultRestTemplate.postForObject("http://localhost:8080/httpPostController/postWithRequestBody", new HttpEntity<>(teacher, headers), String.class);
//这里将JSONString转成带有泛型的实体类,需要创建TypeReference对象
BaseResult<Teacher> baseResult = JSONObject.parseObject(response, new TypeReference<BaseResult<Teacher>>() {
});
log.info(baseResult != null ? baseResult.toString() : null);//BaseResult(code=200, message=成功, data=Teacher(name=李四, age=24, addr=北京, students=[张三, 王五], projectTable={Tus=语文, Mon=数学}))
}
public static Teacher getTeacher() {
Teacher teacher = new Teacher();
teacher.setName("李四");
teacher.setAge(24);
teacher.setAddr("北京");
teacher.setStudents(Lists.list("张三", "王五"));
Map<String, String> map = new HashMap<>();
map.put("Mon", "数学");
map.put("Tus", "语文");
teacher.setProjectTable(map);
return teacher;
}
6.使用exchange方法发送请求
除了上述的方法外,RestTemplate还提供了exchange方法用于自由构建Http请求,此处做简单示例
@Resource
private RestTemplate defaultRestTemplate;
/**
* 发送无body的post请求(get请求同理)
*/
@Test
void exchangeWithoutBody() {
String url = "http://localhost:8080/httpPostController/post";
ResponseEntity<String> responseEntity = defaultRestTemplate.exchange(url, HttpMethod.POST, null, String.class);
log.info(responseEntity.getBody());//{"code":"200","message":"成功","data":"这是无参post请求"}
}
/**
* 发送post请求
*/
@Test
void exchangeWithBody() {
String url = "http://localhost:8080/httpPostController/postWithRequestBody?name={0}&age={1}";
Teacher teacher = getTeacher();
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add("temp_header1", "I'm temp header1");
headers.add("temp_header2", "I'm temp header2");
ResponseEntity<String> responseEntity = defaultRestTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(teacher, headers), String.class, teacher.getName(), teacher.getAge());
log.info(responseEntity.getBody());//{"code":"200","message":"成功","data":{"name":"李四","age":24,"addr":"北京","students":["张三","王五"],"projectTable":{"Tus":"语文","Mon":"数学"}}}
}
public static Teacher getTeacher() {
Teacher teacher = new Teacher();
teacher.setName("李四");
teacher.setAge(24);
teacher.setAddr("北京");
teacher.setStudents(Lists.list("张三", "王五"));
Map<String, String> map = new HashMap<>();
map.put("Mon", "数学");
map.put("Tus", "语文");
teacher.setProjectTable(map);
return teacher;
}