RestTemplate 用法详解(一)

RestTemplate 简介

        RestTemplate 是从 Spring3.0 开始支持的一个 HTTP 请求工具,它提供了常见的REST请求方案的模版,例如 GET 请求、POST 请求、PUT 请求、DELETE 请求以及一些通用的请求执行方法 exchange 以及 execute。RestTemplate 继承自 InterceptingHttpAccessor 并且实现了 RestOperations 接口,其中 RestOperations 接口定义了基本的 RESTful 操作,这些操作在 RestTemplate 中都得到了实现。接下来我们就来看看这些操作方法的使用。

RestTemplate实战使用

        写一个工具类RestUtil,在实际项目中往往使用单例模式来设计RestTemplate

/**
 * RestAPI 调用器
 */
private final static RestTemplate RT;

static {
	SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
	// 设置连接超时时间,单位为毫秒
	requestFactory.setConnectTimeout(30000);
	// 设置读取超时时间,单位为毫秒
	requestFactory.setReadTimeout(30000);
	RT = new RestTemplate(requestFactory);
	// 解决乱码问题
	RT.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
}

public static RestTemplate getRestTemplate() {
	return RT;
}

 在其他地方需要使用时只需一列下行代码即可:

private static RestTemplate restTemplate = RestUtil.getRestTemplate();

POST请求

        POST请求中有三个方法,分别是postForEntity,postForObject,postForLocation。这三类方法最直观的就是返回值类型定义不同,具体如下代码所示:

public <T> ResponseEntity<T> postForEntity(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables) throws RestClientException {
	RequestCallback requestCallback = this.httpEntityCallback(request, responseType);
	ResponseExtractor<ResponseEntity<T>> responseExtractor = this.responseEntityExtractor(responseType);
	return (ResponseEntity)nonNull(this.execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables));
}

@Nullable
public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables) throws RestClientException {
	RequestCallback requestCallback = this.httpEntityCallback(request, responseType);
	HttpMessageConverterExtractor<T> responseExtractor = new HttpMessageConverterExtractor(responseType, this.getMessageConverters(), this.logger);
	return this.execute(url, HttpMethod.POST, requestCallback, responseExtractor, (Object[])uriVariables);
}

@Nullable
// 返回值为URI对象,因为Post请求最常用来添加数据,如果需要将刚刚添加成功的数据的URL返回来,此时就可以使用这个方法
public URI postForLocation(String url, @Nullable Object request, Object... uriVariables) throws RestClientException {
	RequestCallback requestCallback = this.httpEntityCallback(request);
	HttpHeaders headers = (HttpHeaders)this.execute(url, HttpMethod.POST, requestCallback, this.headersExtractor(), uriVariables);
	return headers != null ? headers.getLocation() : null;
}

        参数类型分别为:

        1)String url        请求的url路径       

        2)@Nullable Object request        可为空的请求对象

        3)Class<T> responseType        返回类型的类定义

        4)Object... uriVariables        动态的uri参数,可传递多个

        5)Map<String, ?> uriVariables        以Map方式存储的uri参数

1、postForEntity方法

        参数可以是key/value类型也可以是json串

(一)传递key/value参数

        首先在服务端写一个Post请求的接口

@PostMapping(value = "/synchronizationCar")
public String synchronizationCar(@RequestBody MultiValueMap map) {
	System.out.println(map.get("name"));
	System.out.println(map.get("sex"));
	System.out.println(map.get("description"));
	return  "";
}

        客户端请求代码如下:

public static void main(String[] args) {
	HttpHeaders headers = new HttpHeaders();
	MultiValueMap map = new LinkedMultiValueMap();
	map.add("name", "雷锋");
	map.add("sex", "男");
	map.add("description", "乐于助人的好人");
	HttpEntity entity = new HttpEntity<>(map, headers);
	ResponseEntity<String> json = restTemplate.postForEntity("http://localhost:8099/basics/bisBasicsCar/synchronizationCar", entity, String.class);
}

(二)传递json字符串

        首先服务端解析代码如下:

@PostMapping(value = "/synchronizationCar")
public String synchronizationCar(@RequestBody String s) {
	JSONObject jsonObject = JSONObject.parseObject(s);
	JSONArray jsonArray = jsonObject.getJSONArray("data");
	List<BisBasicsCar> list = jsonArray.toJavaList(BisBasicsCar.class);
	System.out.println(list.size());
	return  "ok";
}

        客户端请求代码如下:

private void basicsSynchronization(){

	//车辆表
	List<BisBasicsCar> list = bisBasicsCarMapper.selectList(null);
	HttpHeaders headers = new HttpHeaders();
	headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
	JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(list));
	//object
	JSONObject jsonObject = new JSONObject();
	jsonObject.put("data", jsonArray);
	HttpEntity entity = new HttpEntity<>(jsonObject, headers);
//        String json = restTemplate.postForObject("http://localhost:8099/basics/bisBasicsCar/synchronizationCar", entity, String.class);
	ResponseEntity<String> json = restTemplate.postForEntity("http://localhost:8099/basics/bisBasicsCar/synchronizationCar", entity, String.class);
	if (json != null){
		/*JSONArray users = json.getJSONArray("data");
		list = users.toJavaList(BisBasicsCar.class);*/
	}
}

        此处注意的有以下几点:

        1、key/value传参要使用LinkedMultiValueMap而不是HashMap

        2、笔者使用的json转换是借用alibaba的第三方包fastjson

        3、server端要接收参数需要用@RequestBody注解,不然无法接收到参数

2、postForObject方法

        先看下源码中关于postForObject有三种不同传参的方法

@Nullable
public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables) throws RestClientException {
	RequestCallback requestCallback = this.httpEntityCallback(request, responseType);
	HttpMessageConverterExtractor<T> responseExtractor = new HttpMessageConverterExtractor(responseType, this.getMessageConverters(), this.logger);
	return this.execute(url, HttpMethod.POST, requestCallback, responseExtractor, (Object[])uriVariables);
}

@Nullable
public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException {
	RequestCallback requestCallback = this.httpEntityCallback(request, responseType);
	HttpMessageConverterExtractor<T> responseExtractor = new HttpMessageConverterExtractor(responseType, this.getMessageConverters(), this.logger);
	return this.execute(url, HttpMethod.POST, requestCallback, responseExtractor, (Map)uriVariables);
}

@Nullable
public <T> T postForObject(URI url, @Nullable Object request, Class<T> responseType) throws RestClientException {
	RequestCallback requestCallback = this.httpEntityCallback(request, responseType);
	HttpMessageConverterExtractor<T> responseExtractor = new HttpMessageConverterExtractor(responseType, this.getMessageConverters());
	return this.execute(url, HttpMethod.POST, requestCallback, responseExtractor);
}

        参数可以是Json字符串,JavaBean对象,也可以是map,其中本质都是使用了HttpEntity对象

(一)传递Json字符串

        传递Json字符串需要手动的将Json字符串添加到HttpEntity,具体做法如下:

public void test(){
	//车辆表
	List<BisBasicsCar> list = bisBasicsCarMapper.selectList(null);
	HttpHeaders headers = new HttpHeaders();
	headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
	JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(list));
	//object
	JSONObject jsonObject = new JSONObject();
	jsonObject.put("data", jsonArray);
	HttpEntity entity = new HttpEntity<>(jsonObject, headers);//@1
	String json = restTemplate.postForObject("http://localhost:8099/basics/bisBasicsCar/synchronizationCar", entity, String.class);
}

        @1:将Json字符串添加到HttpEntity 对象中

(二)传递JavaBean

        有两种做法,一种是手动把JavaBean添加到HttpEntity对象中,一种直接传JavaBean对象

public void test2(){
	BisBasicsCar bisBasicsCar = new BisBasicsCar();
	bisBasicsCar.setCarType("轿车");
	bisBasicsCar.setDriver("司机王师傅");
	bisBasicsCar.setLicenseNumber("沪A888888");
	HttpHeaders headers = new HttpHeaders();
	HttpEntity entity = new HttpEntity<>(bisBasicsCar, headers);//@1
	String json = restTemplate.postForObject("http://localhost:8099/basics/bisBasicsCar/synchronizationCar", entity, String.class);
}

public void test3(){
	BisBasicsCar bisBasicsCar = new BisBasicsCar();
	bisBasicsCar.setCarType("轿车");
	bisBasicsCar.setDriver("司机王师傅");
	bisBasicsCar.setLicenseNumber("沪A888888");
	String json = restTemplate.postForObject("http://localhost:8099/basics/bisBasicsCar/synchronizationCar", bisBasicsCar, String.class);//@2
}

        @1:手动将JavaBean加入到HttpEntity 对象中

        @2:直接传JavaBean对象

        为什么说本质上都是使用了HttpEntity对象呢?

        是因为源码中有这样一段代码:

public HttpEntityRequestCallback(@Nullable Object requestBody, @Nullable Type responseType) {
	super(responseType);
	if (requestBody instanceof HttpEntity) {
		this.requestEntity = (HttpEntity)requestBody;
	} else if (requestBody != null) {
		this.requestEntity = new HttpEntity(requestBody);
	} else {
		this.requestEntity = HttpEntity.EMPTY;
	}

}

        程序会自动判断,如果不是HttpEntity对象就手动添加一次

3、postForLocation

        postForLocation也是提交新资源,提交成功之后,返回新资源的URI,postForLocation的参数和前面两种的参数基本一致,只不过该方法的返回值为Uri,这个只需要服务提供者返回一个Uri即可,该Uri表示新资源的位置。

        然后看下列实际代码中会发现,最终还是使用了HttpEntity对象

public HttpEntityRequestCallback(@Nullable Object requestBody) {
	this(requestBody, (Type)null);//@1
}

public HttpEntityRequestCallback(@Nullable Object requestBody, @Nullable Type responseType) {//@2
	super(responseType);
	if (requestBody instanceof HttpEntity) {
		this.requestEntity = (HttpEntity)requestBody;
	} else if (requestBody != null) {
		this.requestEntity = new HttpEntity(requestBody);
	} else {
		this.requestEntity = HttpEntity.EMPTY;
	}

}

        Java多态的方法,但是还在@1的位置处调用了@2的方法

Java中的RestTemplateSpring框架提供的个用于访问RESTful服务的客户端工具。它提供了组用于HTTP请求的方法,使得我们能够方便地与RESTful服务进行交互。下面是使用RestTemplate的详细步骤。 1. 引入依赖 在pom.xml文件中引入RestTemplate依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.3.0.RELEASE</version> </dependency> ``` 2. 创建RestTemplate对象 可以通过Spring的依赖注入来创建RestTemplate对象,也可以直接new个对象。下面是使用依赖注入创建RestTemplate对象的示例: ``` @Autowired private RestTemplate restTemplate; ``` 3. 发送HTTP请求 RestTemplate提供了多种发送HTTP请求的方法,包括GET、POST、PUT、DELETE等。这里以GET请求为例: ``` String url = "http://example.com/get?param1=value1&param2=value2"; String result = restTemplate.getForObject(url, String.class); ``` 其中,url是请求的URL地址,result是响应的字符串。getForObject()方法会将响应的JSON字符串转换成Java对象并返回。 4. 发送带有参数的HTTP请求 可以通过RestTemplate的exchange()方法发送带有参数的HTTP请求: ``` String url = "http://example.com/post"; MultiValueMap<String, String> params= new LinkedMultiValueMap<>(); params.add("param1", "value1"); params.add("param2", "value2"); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params, headers); String result = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class).getBody(); ``` 其中,url是请求的URL地址,params是请求的参数,headers是请求头,requestEntity是请求体,result是响应的字符串。 5. 发送带有请求体的HTTP请求 可以通过RestTemplate的postForObject()方法发送带有请求体的HTTP请求: ``` String url = "http://example.com/post"; String requestJson = "{\"param1\":\"value1\",\"param2\":\"value2\"}"; HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity<String> requestEntity = new HttpEntity<>(requestJson, headers); String result = restTemplate.postForObject(url, requestEntity, String.class); ``` 其中,url是请求的URL地址,requestJson是请求的JSON字符串,headers是请求头,requestEntity是请求体,result是响应的字符串。 6. 处理响应 RestTemplate发送的HTTP请求的响应可以是字符串、字节数组、输入流、Java对象等。可以根据需要选择不同的处理方式: ``` // 响应为字符串 String result = restTemplate.getForObject(url, String.class); // 响应为字节数组 byte[] result = restTemplate.getForObject(url, byte[].class); // 响应为输入流 InputStream result = restTemplate.getForObject(url, InputStream.class); // 响应为Java对象 Response response = restTemplate.getForObject(url, Response.class); ``` 这里的Response是Java对象,它的属性与响应的JSON字符串对应。可以通过使用Jackson等JSON转换框架将JSON字符串转换成Java对象。 以上就是使用RestTemplate发送HTTP请求的详细步骤。需要注意的是,RestTemplate在处理HTTP请求时,会抛出些异常,例如HttpStatusCodeException、ResourceAccessException等,需要进行适当的异常处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zfy_220

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值