Spring MVC用RestTemplate访问REST服务

Java Web开发中,我们通常需要通过GET、POST请求其他系统提供的服务。其中,JDK自带的HttpURLConnection、Apache HttpClient等方式都可以实现。当然,这些方式都有一个很明显的缺陷,那就是代码很繁琐。而Spring提供的RestTemplate封装了这些库的实现,可以让我们的HTTP请求更加简洁、直观。

在Java Web开发中,我们通常需要通过GET、POST请求其他系统提供的服务。其中,JDK自带的HttpURLConnection、Apache HttpClient等方式都可以实现。当然,这些方式都有一个很明显的缺陷,那就是代码很繁琐。而Spring提供的RestTemplate封装了这些库的实现,可以让我们的HTTP请求更加简洁、直观。

在RestTemplate中定义了11个独立的操作,它们分别是:

方法 描述
 delete() 在特定的URL上对资源执行HTTP DELETE操作
 exchange() 在URL上执行特定的HTTP方法,返回的ResponseEntity包含了响应体所映射成的对象
 execute() 在URL上执行特定的HTTP方法,返回一个从响应体映射得到的对象
 getForEntity() 发送一个HTTP GET请求,返回的ResponseEntity包含了响应体所映射成的对象
 getForObject() 发送一个HTTP GET请求,返回根据响应体映射形成的对象
 postForEntity() POST数据到一个URL,返回的ResponseEntity包含了响应体所映射成的对象
 postForLocation() POST数据到一个URL,返回新创建资源的URL
 postForObject() POST数据到一个URL,返回根据响应体映射形成的对象
 put() PUT资源到特定的URL
 headForHeaders() 发送HTTP HEAD请求,返回包含特定资源URL的HTTP头
 optionsForAllow() 发送HTTP OPTIONS请求,返回对特定URL的Allow头信息

接下来,我将对常用的几个方法分别介绍。

(1)在项目中添加依赖

<!-- Jackson对自动解析JSON和XML格式的支持 -->
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
<!-- HttpClient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<!-- Fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.46</version>
</dependency>
<!-- Jackson对自动解析JSON和XML格式的支持 -->
<dependency>
    <groupId>com.fasterxml.jackson.jaxrs</groupId>
    <artifactId>jackson-jaxrs-json-provider</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
</dependency>
 
<!-- HttpClient -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
</dependency>
 
<!-- Fastjson -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.46</version>
</dependency>

(2)在项目中注入RestTemplate

在注入 RestTemplate 的 bean 的时候,可以通过 ClientHttpRequestFactory 指定 RestTemplate 发起 HTTP 请求的底层实现所采用的类库。对此,ClientHttpRequestFactory 接口主要提供了以下两种实现方法:

i)SimpleClientHttpRequestFactory:

也就是底层使用 java.net 包提供的方式创建 Http 连接请求。示例代码如下:

package cn.zifangsky.springbootdemo.config;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {

	/**
	 * 返回RestTemplate
	 * @param factory
	 * @return
	 */
	@Bean
	public RestTemplate restTemplate(ClientHttpRequestFactory factory){
		//消息转换器,一般情况下可以省略,只需要添加相关依赖即可
		//List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
		//        messageConverters.add(new StringHttpMessageConverter(Charset.forName("UTF-8")));
		//        messageConverters.add(new FormHttpMessageConverter());
		//        messageConverters.add(new MappingJackson2XmlHttpMessageConverter());
		//        messageConverters.add(new MappingJackson2HttpMessageConverter());
		RestTemplate restTemplate = new RestTemplate(factory);
		//restTemplate.setMessageConverters(messageConverters);
		return restTemplate;
	}

	/**
	 * ClientHttpRequestFactory接口的第一种实现方式,即:
	 * SimpleClientHttpRequestFactory:底层使用java.net包提供的方式创建Http连接请求
	 * @return
	 */
	@Bean
	public SimpleClientHttpRequestFactory simpleClientHttpRequestFactory(){
		SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
		requestFactory.setReadTimeout(5000);
		requestFactory.setConnectTimeout(5000);
		return requestFactory;
	}
}

package cn.zifangsky.springbootdemo.config;
 
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
import org.springframework.web.client.RestTemplate;
 
@Configuration
public class RestTemplateConfig {
 
    /**
     * 返回RestTemplate
     * @param factory
     * @return
     */
    @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory factory){
        //消息转换器,一般情况下可以省略,只需要添加相关依赖即可
//        List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
//        messageConverters.add(new StringHttpMessageConverter(Charset.forName("UTF-8")));
//        messageConverters.add(new FormHttpMessageConverter());
//        messageConverters.add(new MappingJackson2XmlHttpMessageConverter());
//        messageConverters.add(new MappingJackson2HttpMessageConverter());
        
        RestTemplate restTemplate = new RestTemplate(factory);
//        restTemplate.setMessageConverters(messageConverters);
        
        return restTemplate;
    }
    
    /**
     * ClientHttpRequestFactory接口的第一种实现方式,即:
     * SimpleClientHttpRequestFactory:底层使用java.net包提供的方式创建Http连接请求
     * @return
     */
    @Bean
    public SimpleClientHttpRequestFactory simpleClientHttpRequestFactory(){
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setReadTimeout(5000);
        requestFactory.setConnectTimeout(5000);
        return requestFactory;
    }
}

ii)HttpComponentsClientHttpRequestFactory(推荐使用)

也就是底层使用Httpclient连接池的方式创建Http连接请求。示例代码如下:

package cn.zifangsky.springbootdemo.config;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.http.Header;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeader;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {

	/**
	 * 返回RestTemplate
	 * @param factory
	 * @return
	 */
	@Bean
	public RestTemplate restTemplate(ClientHttpRequestFactory factory){
		//消息转换器,Spring Boot环境可省略,只需要添加相关依赖即可
//		List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
//        messageConverters.add(new StringHttpMessageConverter(Charset.forName("UTF-8")));
//        messageConverters.add(new FormHttpMessageConverter());
//        messageConverters.add(new MappingJackson2XmlHttpMessageConverter());
//        messageConverters.add(new MappingJackson2HttpMessageConverter());
		
		RestTemplate restTemplate = new RestTemplate(factory);
//		restTemplate.setMessageConverters(messageConverters);
		return restTemplate;
	}
	

	/**
	 * ClientHttpRequestFactory接口的另一种实现方式(推荐使用),即:
	 * HttpComponentsClientHttpRequestFactory:底层使用Httpclient连接池的方式创建Http连接请求
	 * @return
	 */
	@Bean
	public HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory(){
		//Httpclient连接池,长连接保持30秒
		PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(30, TimeUnit.SECONDS);

		//设置总连接数
		connectionManager.setMaxTotal(1000);
		//设置同路由的并发数
		connectionManager.setDefaultMaxPerRoute(1000);

		//设置header
		List<Header> headers = new ArrayList<Header>();
		headers.add(new BasicHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04"));
		headers.add(new BasicHeader("Accept-Encoding", "gzip, deflate"));
		headers.add(new BasicHeader("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3"));
		headers.add(new BasicHeader("Connection", "keep-alive"));

		//创建HttpClient
        HttpClient httpClient = HttpClientBuilder.create()
                .setConnectionManager(connectionManager)
                .setDefaultHeaders(headers)
                .setRetryHandler(new DefaultHttpRequestRetryHandler(3, true)) //设置重试次数
                .setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy()) //设置保持长连接
                .build();

        //创建HttpComponentsClientHttpRequestFactory实例
        HttpComponentsClientHttpRequestFactory requestFactory = 
				new HttpComponentsClientHttpRequestFactory(httpClient);

        //设置客户端和服务端建立连接的超时时间
        requestFactory.setConnectTimeout(5000);
		//设置客户端从服务端读取数据的超时时间
        requestFactory.setReadTimeout(5000);
        //设置从连接池获取连接的超时时间,不宜过长
        requestFactory.setConnectionRequestTimeout(200);
        //缓冲请求数据,默认为true。通过POST或者PUT大量发送数据时,建议将此更改为false,以免耗尽内存
        requestFactory.setBufferRequestBody(false);
        return requestFactory;
	}
}


package cn.zifangsky.springbootdemo.config;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.http.Header;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeader;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {

    /**
     * 返回RestTemplate
     * @param factory
     * @return
     */
    @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory factory){
        //消息转换器,Spring Boot环境可省略,只需要添加相关依赖即可
//        List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
//        messageConverters.add(new StringHttpMessageConverter(Charset.forName("UTF-8")));
//        messageConverters.add(new FormHttpMessageConverter());
//        messageConverters.add(new MappingJackson2XmlHttpMessageConverter());
//        messageConverters.add(new MappingJackson2HttpMessageConverter());
        RestTemplate restTemplate = new RestTemplate(factory);
//        restTemplate.setMessageConverters(messageConverters);
        return restTemplate;
    }

    /**
     * ClientHttpRequestFactory接口的另一种实现方式(推荐使用),即:
     * HttpComponentsClientHttpRequestFactory:底层使用Httpclient连接池的方式创建Http连接请求
     * @return
     */
    @Bean
    public HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory(){
        //Httpclient连接池,长连接保持30秒
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(30, TimeUnit.SECONDS);

        //设置总连接数
        connectionManager.setMaxTotal(1000);
        //设置同路由的并发数
        connectionManager.setDefaultMaxPerRoute(1000);
        
        //设置header
        List<Header> headers = new ArrayList<Header>();
        headers.add(new BasicHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04"));
        headers.add(new BasicHeader("Accept-Encoding", "gzip, deflate"));
        headers.add(new BasicHeader("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3"));
        headers.add(new BasicHeader("Connection", "keep-alive"));

        //创建HttpClient
        HttpClient httpClient = HttpClientBuilder.create()
                .setConnectionManager(connectionManager)
                .setDefaultHeaders(headers)
                .setRetryHandler(new DefaultHttpRequestRetryHandler(3, true)) //设置重试次数
                .setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy()) //设置保持长连接
                .build();

        //创建HttpComponentsClientHttpRequestFactory实例
        HttpComponentsClientHttpRequestFactory requestFactory = 
                new HttpComponentsClientHttpRequestFactory(httpClient);
        //设置客户端和服务端建立连接的超时时间
        requestFactory.setConnectTimeout(5000);
        //设置客户端从服务端读取数据的超时时间
        requestFactory.setReadTimeout(5000);
        //设置从连接池获取连接的超时时间,不宜过长
        requestFactory.setConnectionRequestTimeout(200);
        //缓冲请求数据,默认为true。通过POST或者PUT大量发送数据时,建议将此更改为false,以免耗尽内存
        requestFactory.setBufferRequestBody(false);
        return requestFactory;
    }
}

(3)使用getForObject()方法发起GET请求

getForObject() 方法实际上是对 getForEntity() 方法的进一步封装,二者用法类似。 唯一的区别在于 getForObject() 方法只返回所请求类型的对象, 而getForEntity() 方法会返回请求的对象以及响应的Header、响应状态码等额外信息。

三个getForObject()方法的签名如下:

<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;
<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;

示例代码如下:

package cn.zifangsky.SpringBootDemo.controller;

import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.client.RestTemplate;
import cn.zifangsky.springbootdemo.config.RestTemplateConfig;
import cn.zifangsky.springbootdemo.config.WebMvcConfig;
import cn.zifangsky.springbootdemo.model.DemoObj;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={WebMvcConfig.class,RestTemplateConfig.class})
@WebAppConfiguration("src/main/resources")
public class TestRestTemplate {

	@Autowired
	private RestTemplate restTemplate;

	/**
	 * 测试最基本的Get请求
	 */
	@Test
	public void testGetMethod1(){
		DemoObj obj = restTemplate.getForObject("https://127.0.0.1:9090/rest/testJson2?id={1}&name={2}",
				DemoObj.class, 1, "Tom");
		System.out.println(obj);
	}
}


package cn.zifangsky.SpringBootDemo.controller;

import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.client.RestTemplate;
import cn.zifangsky.springbootdemo.config.RestTemplateConfig;
import cn.zifangsky.springbootdemo.config.WebMvcConfig;
import cn.zifangsky.springbootdemo.model.DemoObj;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={WebMvcConfig.class,RestTemplateConfig.class})
@WebAppConfiguration("src/main/resources")
public class TestRestTemplate {

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 测试最基本的Get请求
     */
    @Test
    public void testGetMethod1(){
        DemoObj obj = restTemplate.getForObject("https://127.0.0.1:9090/rest/testJson2?id={1}&name={2}",
				DemoObj.class, 1, "Tom");
        System.out.println(obj);
    }

}

注:本篇文章的单元测试请求的REST服务均来源于上一篇文章:https://www.zifangsky.cn/1215.html

上面代码设置请求参数使用了数字占位符,同时getForObject()方法的最后一个参数是一个可变长度的参数,用于一一替换前面的占位符。当然,除了这种方式之外,还可以使用Map来设置参数,比如:

/**
 * 测试Get请求另一种设置参数的方式
 */
@Test
public void testGetMethod2(){
	Map<String, String> uriVariables = new HashMap<String, String>();
	uriVariables.put("var_id", "1");
	uriVariables.put("var_name", "Tom");

	DemoObj obj = restTemplate.getForObject("https://127.0.0.1:9090/rest/testJson2?id={var_id}&name={var_name}",
			DemoObj.class, uriVariables);
	System.out.println(obj);
}

/**
 * 测试Get请求另一种设置参数的方式
 */
@Test
public void testGetMethod2(){
	Map<String, String> uriVariables = new HashMap<String, String>();
	uriVariables.put("var_id", "1");
	uriVariables.put("var_name", "Tom");

	DemoObj obj = restTemplate.getForObject("https://127.0.0.1:9090/rest/testJson2?id={var_id}&name={var_name}",
			DemoObj.class, uriVariables);
	System.out.println(obj);
}

运行单元测试之后,最后输出如下:

DemoObj [id=2, name=Tom Ret]

此外需要注意的是,由于上面代码只是简单的单元测试,因此请求URL就直接硬编码在代码中了。实际开发则需要将之配置到配置文件或者Zookeeper、Redis中。比如这样:

package cn.zifangsky.springbootdemo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import cn.zifangsky.springbootdemo.model.DemoObj;

@RestController
@RequestMapping("/restTemplate")
public class RestTemplateController {
	@Value("${SERVER_URL}")
	private String SERVER_URL;

	@Autowired
	private RestTemplate restTemplate;

	@RequestMapping(path="/getDemoObj",produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
	public DemoObj getDemoObj(){
		DemoObj obj = restTemplate.getForObject(SERVER_URL + "/rest/testXML?id={1}&name={2}",
				DemoObj.class, 1,"Tom");
		return obj;
	}
}

package cn.zifangsky.springbootdemo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import cn.zifangsky.springbootdemo.model.DemoObj;

@RestController
@RequestMapping("/restTemplate")
public class RestTemplateController {

    @Value("${SERVER_URL}")
    private String SERVER_URL;

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping(path="/getDemoObj",produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
    public DemoObj getDemoObj(){
        DemoObj obj = restTemplate.getForObject(SERVER_URL + "/rest/testXML?id={1}&name={2}",
				DemoObj.class, 1,"Tom");
        return obj;
    }
}

(4)使用getForEntity()方法发起GET请求

三个getForEntity()方法的签名如下:

<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> 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;

示例代码如下:

/**
 * 测试Get请求返回详细信息,包括:响应正文、响应状态码、响应Header等
 */
@Test
public void testGetMethod3(){
    ResponseEntity<DemoObj> responseEntity = restTemplate.getForEntity(
"https://127.0.0.1:9090/rest/testJson2?id={1}&name={2}", DemoObj.class, 1,"Tom");

    DemoObj body = responseEntity.getBody();
    int statusCodeValue = responseEntity.getStatusCodeValue();
    HttpHeaders headers = responseEntity.getHeaders();
    System.out.println("responseEntity.getBody():" + body);
    System.out.println("responseEntity.getStatusCodeValue():" + statusCodeValue);
    System.out.println("responseEntity.getHeaders():" + headers);
}

/**
 * 测试Get请求返回详细信息,包括:响应正文、响应状态码、响应Header等
 */
@Test
public void testGetMethod3(){
    ResponseEntity<DemoObj> responseEntity = restTemplate.getForEntity(
"https://127.0.0.1:9090/rest/testJson2?id={1}&name={2}", DemoObj.class, 1,"Tom");

    DemoObj body = responseEntity.getBody();
    int statusCodeValue = responseEntity.getStatusCodeValue();
    HttpHeaders headers = responseEntity.getHeaders();

    System.out.println("responseEntity.getBody():" + body);
    System.out.println("responseEntity.getStatusCodeValue():" + statusCodeValue);
    System.out.println("responseEntity.getHeaders():" + headers);
}

运行单元测试之后,最后输出如下:

responseEntity.getBody():DemoObj [id=2, name=Tom Ret]

responseEntity.getStatusCodeValue():200

responseEntity.getHeaders():{Date=[Fri, 09 Feb 2018 06:22:28 GMT], Content-Type=[application/json;charset=utf-8], Transfer-Encoding=[chunked]}

(5)使用postForObject()方法发起POST请求

在RestTemplate中,POST请求跟GET请求类似,也可以使用如下三个方法来请求:

<T> T postForObject(String url, Object request, Class<T> responseType, Object... uriVariables) throws RestClientException;
<T> T postForObject(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException;
<T> T postForObject(URI url, Object request, Class<T> responseType) throws RestClientException;
<T> T postForObject(String url, Object request, Class<T> responseType, Object... uriVariables) throws RestClientException;
<T> T postForObject(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException;
<T> T postForObject(URI url, Object request, Class<T> responseType) throws RestClientException;

示例代码如下:

/**
 * 测试最基本的Post请求
 */
@Test
public void testPostMethod1(){
    DemoObj request = new DemoObj(1l, "Tim");
    DemoObj obj = restTemplate.postForObject("https://127.0.0.1:9090/rest/testJson1", request, DemoObj.class);
    System.out.println(obj);
}

/**
 * 测试最基本的Post请求
 */
@Test
public void testPostMethod1(){
    DemoObj request = new DemoObj(1l, "Tim");
    DemoObj obj = restTemplate.postForObject("https://127.0.0.1:9090/rest/testJson1", request, DemoObj.class);
    System.out.println(obj);
}

运行单元测试之后,最后输出如下:

DemoObj [id=2, name=Tim Ret]

(6)使用postForEntity()方法发起POST请求

三个postForEntity()方法的签名如下:

<T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables) throws RestClientException;
<T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException;
<T> ResponseEntity<T> postForEntity(URI url, Object request, Class<T> responseType) throws RestClientException;
<T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables) throws RestClientException;
<T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException;
<T> ResponseEntity<T> postForEntity(URI url, Object request, Class<T> responseType) throws RestClientException;

示例代码如下:

/**
 * 测试Post请求返回详细信息,包括:响应正文、响应状态码、响应Header等
 */
@Test
public void testPostMethod2(){
    DemoObj request = new DemoObj(1l, "Tim");
    ResponseEntity<DemoObj> responseEntity = restTemplate.postForEntity(
"https://127.0.0.1:9090/rest/testJson1", request, DemoObj.class);

    DemoObj body = responseEntity.getBody();
    int statusCodeValue = responseEntity.getStatusCodeValue();
    HttpHeaders headers = responseEntity.getHeaders();
    System.out.println("responseEntity.getBody():" + body);
    System.out.println("responseEntity.getStatusCodeValue():" + statusCodeValue);
    System.out.println("responseEntity.getHeaders():" + headers);
}


/**
 * 测试Post请求返回详细信息,包括:响应正文、响应状态码、响应Header等
 */
@Test
public void testPostMethod2(){
    DemoObj request = new DemoObj(1l, "Tim");
    ResponseEntity<DemoObj> responseEntity = restTemplate.postForEntity(
"https://127.0.0.1:9090/rest/testJson1", request, DemoObj.class);

    DemoObj body = responseEntity.getBody();
    int statusCodeValue = responseEntity.getStatusCodeValue();
    HttpHeaders headers = responseEntity.getHeaders();
    System.out.println("responseEntity.getBody():" + body);
    System.out.println("responseEntity.getStatusCodeValue():" + statusCodeValue);
    System.out.println("responseEntity.getHeaders():" + headers);
}

运行单元测试之后,最后输出如下:

responseEntity.getBody():DemoObj [id=2, name=Tim Ret]

responseEntity.getStatusCodeValue():200

responseEntity.getHeaders():{Date=[Fri, 09 Feb 2018 06:32:02 GMT], Content-Type=[application/json;charset=utf-8], Transfer-Encoding=[chunked]}

(7)使用exchange()方法执行指定的HTTP请求

exchange()方法跟上面的getForObject()、getForEntity()、postForObject()、postForEntity()等方法不同之处在于它可以指定请求的HTTP类型。示例代码如下:

/**
 * 测试Exchange请求
 */
@Test
public void testExchange(){
    //设置header
    HttpHeaders headers = new HttpHeaders();
    headers.add("Content-Type", "application/x-zifangsky");

    //设置参数
    String requestBody = "1#Converter";
    HttpEntity<String> requestEntity = new HttpEntity<String>(requestBody,headers);

    ResponseEntity<String> responseEntity = restTemplate.exchange(
"https://127.0.0.1:9090/convert", HttpMethod.POST, requestEntity, String.class);

    System.out.println("responseEntity.getBody():" + responseEntity.getBody());
    System.out.println("responseEntity.getHeaders():" + responseEntity.getHeaders());
}

/**
 * 测试Exchange请求
 */
@Test
public void testExchange(){
    //设置header
    HttpHeaders headers = new HttpHeaders();
    headers.add("Content-Type", "application/x-zifangsky");

    //设置参数
    String requestBody = "1#Converter";
    HttpEntity<String> requestEntity = new HttpEntity<String>(requestBody,headers);

    ResponseEntity<String> responseEntity = restTemplate.exchange(
"https://127.0.0.1:9090/convert", HttpMethod.POST, requestEntity, String.class);
    System.out.println("responseEntity.getBody():" + responseEntity.getBody());
    System.out.println("responseEntity.getHeaders():" + responseEntity.getHeaders());
}

运行单元测试之后,最后输出如下:

responseEntity.getBody():{“id”:2,”name”:”Converter Ret”}

responseEntity.getHeaders():{Date=[Fri, 09 Feb 2018 06:42:29 GMT], Content-Type=[application/x-zifangsky], Transfer-Encoding=[chunked]}

参考资料:

https://segmentfault.com/a/1190000011093597 

https://rensanning.iteye.com/blog/2362105 

https://www.zifangsky.cn/1221.html 

我们一定要给自己提出这样的任务:第一,学习,第二是学习,第三还是学习。 —— 列宁
0 不喜欢
说说我的看法 -
全部评论(
没有评论
关于
本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,请来信告知:hxstrive@outlook.com
公众号