[RestTemplate] 配置 及 调用POST GET请求 demo
目录01. RestTemplate简介A). 简要说明B). RestTemplate有两个构造方法C). ClientHttpRequestFactory的两种实现02. Spring的RestTemplate对Post/Get的常用接口A). Post请求APIB). Get请求API03. 配置及使用A). 配置文件B). 测试使用附录及示例:...
目录
C). ClientHttpRequestFactory的两种实现
02. Spring的RestTemplate对Post/Get的常用接口
B). RestClient.java / spring-restTemplate.xml
01. RestTemplate简介
A). 简要说明
RestTemplate是Spring提供的用于访问Rest服务的客户端, RestTemplate提供了多种便捷访问远程Http服务的方法, 能够大大提高客户端的编写效率.
B). RestTemplate有两个构造方法
分别是:
a). 第一个构造方法为默认初始化, 无法控制超时时间;
b). 第二个构造方法可以传入ClientHttpRequestFactory参数, 设置该工厂类的timeout属性可以控制超时时间;
结论: 由于我们经常需要对请求超时进行设置并进行后续处理, 因此选用第二个构造方法.
C). ClientHttpRequestFactory的两种实现
a). SimpleClientHttpRequestFactory: 使用J2SE提供的方式(java.net包提供的方式)创建底层的Http请求连接;
b). HttpComponentsClientHttpRequestFactory: 使用HttpClient访问远程的Http服务, 使用HttpClient可以配置连接池和证书等信息.
注意: RestTemplate默认是使用SimpleClientHttpRequestFactory,内部是调用jdk的HttpConnection, 默认超时为-1
02. Spring的RestTemplate对Post/Get的常用接口
A). Post请求API
public <T> T postForObject(String url, Object request, Class<T> responseType, Object... uriVariables) throws RestClientException
public <T> T postForObject(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException
public <T> T postForObject(URI url, Object request, Class<T> responseType) throws RestClientException
B). Get请求API
public <T> T getForObject(String url, Class<T> responseType, Object... urlVariables) throws RestClientException
public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> urlVariables) throws RestClientException
public <T> T getForObject(URI url, Class<T> responseType) throws RestClientException
例如:
String result = restTemplate.getForObject("http://example.com/hotels/{hotel}/bookings/{booking}", String.class,"42", "21");
String message = restTemplate.getForObject("http://localhost:8080/yongbarservice/appstore/appgoods/restTemplate?name=zhaoshijie&id=80", String.class);
Map<String, String> vars = Collections.singletonMap("hotel", "42");
String result = restTemplate.getForObject("http://example.com/hotels/{hotel}/rooms/{hotel}", String.class, vars);
03. 配置及使用
A). 配置文件
pom.xml
RestClient.java
spring-restTemplate.xml
B). 测试使用
TestGetMain.java
TestPostMain.java
附录及示例:
A). pom.xml
主要关注需要引入的jar包, jar包版本过低会出现很多问题, 什么版本合适请自行处理; 懒人请按如下或更高版本操作...
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cntv.learn</groupId>
<artifactId>restTemplate_v3.0</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<junit.version>4.12</junit.version>
<slf4j.version>1.7.25</slf4j.version>
<spring.version>4.3.18.RELEASE</spring.version>
<jackson.version>2.9.4</jackson.version>
<fastjson.version>1.2.47</fastjson.version>
<httpclient.version>4.5.2</httpclient.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- 映入JSON -->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-xml -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${httpclient.version}</version>
</dependency>
</dependencies>
</project>
B). RestClient.java / spring-restTemplate.xml
根据使用工厂类的不同(SimpleClientHttpRequestFactory, 或者 HttpComponentsClientHttpRequestFactory), 配置
restTemplate分为两种, 具体配置如下:
01-01. spring-restTemplate.xml 使用 SimpleClientHttpRequestFactory
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
default-autowire="byName" default-lazy-init="true">
<!--方式一、使用jdk的实现-->
<bean id="ky.requestFactory" class="org.springframework.http.client.SimpleClientHttpRequestFactory">
<property name="readTimeout" value="10000"/>
<property name="connectTimeout" value="5000"/>
</bean>
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
<constructor-arg ref="ky.requestFactory"/>
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.FormHttpMessageConverter"/>
<bean class="org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter"/>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
</beans>
01-02. RestClient.java 使用 SimpleClientHttpRequestFactory
package com.cntv.learn.client;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
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.stereotype.Component;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import javax.annotation.PostConstruct;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
/**
* @author LiuDong
* @msg 第一种以类的方式获取restTemplate
*/
@Component
@Lazy(false)
public class RestClient {
private static final Logger LOGGER = LoggerFactory.getLogger(RestClient.class);
private static RestTemplate restTemplate;
static {
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setReadTimeout(5000);
requestFactory.setConnectTimeout(5000);
// 添加转换器
List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
messageConverters.add(new FormHttpMessageConverter());
messageConverters.add(new MappingJackson2XmlHttpMessageConverter());
messageConverters.add(new MappingJackson2HttpMessageConverter());
messageConverters.add(new StringHttpMessageConverter(Charset.forName("UTF-8")));
restTemplate = new RestTemplate(messageConverters);
restTemplate.setRequestFactory(requestFactory);
restTemplate.setErrorHandler(new DefaultResponseErrorHandler());
LOGGER.info("SimpleRestClient初始化完成");
}
private RestClient() {
}
@PostConstruct
public static RestTemplate getClient() {
return restTemplate;
}
}
02-01. spring-restTemplate.xml 使用 HttpComponentsClientHttpRequestFactory
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
default-autowire="byName" default-lazy-init="true">
<!--方式二: 使用httpclient的实现,带连接池(在httpclient4.3版本后才有)-->
<bean id="httpClientBuilder" class="org.apache.http.impl.client.HttpClientBuilder" factory-method="create">
<property name="connectionManager">
<bean class="org.apache.http.impl.conn.PoolingHttpClientConnectionManager">
<!--整个连接池的并发-->
<property name="maxTotal" value="50"/>
<!--每个主机的并发-->
<property name="defaultMaxPerRoute" value="50"/>
</bean>
</property>
<!--开启重试-->
<property name="retryHandler">
<bean class="org.apache.http.impl.client.DefaultHttpRequestRetryHandler">
<constructor-arg value="2"/>
<constructor-arg value="true"/>
</bean>
</property>
<property name="defaultHeaders">
<list>
<bean class="org.apache.http.message.BasicHeader">
<constructor-arg value="Content-Type"/>
<constructor-arg value="text/html;charset=UTF-8"/>
</bean>
<bean class="org.apache.http.message.BasicHeader">
<constructor-arg value="Accept-Encoding"/>
<constructor-arg value="gzip,deflate"/>
</bean>
<bean class="org.apache.http.message.BasicHeader">
<constructor-arg value="Accept-Language"/>
<constructor-arg value="zh-CN"/>
</bean>
</list>
</property>
</bean>
<bean id="httpClient" factory-bean="httpClientBuilder" factory-method="build"/>
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
<property name="messageConverters">
<list value-type="org.springframework.http.converter.HttpMessageConverter">
<bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/>
<bean class="org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter"/>
<bean class="org.springframework.http.converter.FormHttpMessageConverter"/>
<bean class="org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter"/>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes" value="application/json;charset=UTF-8" />
</bean>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<!--<property name="supportedMediaTypes" value="text/html;charset=UTF-8" />-->
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
</list>
</property>
<property name="requestFactory">
<bean class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
<constructor-arg ref="httpClient"/>
<!--连接时间(毫秒)-->
<property name="connectTimeout" value="20000"/>
<!--读取时间(毫秒)-->
<property name="readTimeout" value="20000"/>
</bean>
</property>
</bean>
</beans>
02-02. RestClient.java 使用 HttpComponentsClientHttpRequestFactory
package com.cntv.learn.client;
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.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
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.stereotype.Component;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import javax.annotation.PostConstruct;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Component
@Lazy(false)
public class RestClient {
private static final Logger LOGGER = LoggerFactory.getLogger(RestClient.class);
private static RestTemplate restTemplate;
static {
// 长连接保持30秒
PoolingHttpClientConnectionManager pollingConnectionManager = new PoolingHttpClientConnectionManager(30, TimeUnit.SECONDS);
// 总连接数
pollingConnectionManager.setMaxTotal(1000);
// 同路由的并发数
pollingConnectionManager.setDefaultMaxPerRoute(1000);
HttpClientBuilder httpClientBuilder = HttpClients.custom();
httpClientBuilder.setConnectionManager(pollingConnectionManager);
// 重试次数,默认是3次,没有开启
httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(2, true));
// 保持长连接配置,需要在头添加Keep-Alive
httpClientBuilder.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy());
List<Header> headers = new ArrayList<>();
headers.add(new BasicHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.16 Safari/537.36"));
headers.add(new BasicHeader("Accept-Encoding", "gzip,deflate"));
headers.add(new BasicHeader("Accept-Language", "zh-CN"));
headers.add(new BasicHeader("Connection", "Keep-Alive"));
httpClientBuilder.setDefaultHeaders(headers);
HttpClient httpClient = httpClientBuilder.build();
// httpClient连接配置,底层是配置RequestConfig
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
// 连接超时
clientHttpRequestFactory.setConnectTimeout(5000);
// 数据读取超时时间,即SocketTimeout
clientHttpRequestFactory.setReadTimeout(5000);
// 连接不够用的等待时间,不宜过长,必须设置,比如连接不够用时,时间过长将是灾难性的
clientHttpRequestFactory.setConnectionRequestTimeout(200);
// 缓冲请求数据,默认值是true。通过POST或者PUT大量发送数据时,建议将此属性更改为false,以免耗尽内存。
// clientHttpRequestFactory.setBufferRequestBody(false);
// 添加内容转换器
List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
messageConverters.add(new FormHttpMessageConverter());
messageConverters.add(new MappingJackson2XmlHttpMessageConverter());
messageConverters.add(new MappingJackson2HttpMessageConverter());
messageConverters.add(new StringHttpMessageConverter(Charset.forName("UTF-8")));
restTemplate = new RestTemplate(messageConverters);
restTemplate.setRequestFactory(clientHttpRequestFactory);
restTemplate.setErrorHandler(new DefaultResponseErrorHandler());
LOGGER.info("RestClient初始化完成");
}
private RestClient() {
}
@PostConstruct
public static RestTemplate getClient() {
return restTemplate;
}
}
C). TestGetMain.java
参照 调用Get请求接口API , spring-restTemplate.xml的调用如下:
package com.cntv.learn;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
/**
* @author : LiuDong
* @description : 莉莉
* @date : Created in 2018/7/10 15:05
*/
public class TestGetMain {
private static final Logger LOGGER = LoggerFactory.getLogger(TestGetMain.class);
public static void main(String[] args) {
// 获取app上下文
String configLocation = "config/spring-restTemplate.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(configLocation);
// 获取userService对象
RestTemplate restTemplate = (RestTemplate) context.getBean("restTemplate");
testRestTemplateForPostV2(restTemplate);
}
/**
* 方式一: 调用Get请求
* text请求, json响应
* @param restTemplate 调用http请求
*/
private static void testRestTemplateForPostV2(RestTemplate restTemplate) {
// 1-1. . 请求参数
// Map<String, String> urlVariables = new HashMap<>();
// urlVariables.put("host", ""www.lala.com");
String urlVariables = "www.lala.com";
// 1-2. 请求地址
String url = "http://{host}/projectName/saveSxPolicy?username=ss&age=18";
// 2-0. 调用
JSONObject exchange;
try {
exchange = restTemplate.getForObject(url, JSONObject.class, urlVariables);
LOGGER.info(exchange.toString());
System.out.println(exchange.toString());
} catch (RestClientException e) {
LOGGER.info("请求失败...");
System.out.println("请求失败: " + e.getMessage());
}
}
}
D). TestPostMain.java
参照 调用Post请求接口API , spring-restTemplate.xml的调用如下:
package com.cntv.learn;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
/**
* @author : LiuDong
* @description : 莉莉
* @date : Created in 2018/7/10 15:05
*/
public class TestPostMain {
private static final String TOKEN = "3ffe8a64-10cf-4d0e-b7f3-0efc05824376";
private static final Logger LOGGER = LoggerFactory.getLogger(TestPostMain.class);
public static void main(String[] args) {
// 获取app上下文
String configLocation = "config/spring-restTemplate.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(configLocation);
// 获取userService对象
RestTemplate restTemplate = (RestTemplate) context.getBean("restTemplate");
testRestTemplateForPostV1(restTemplate);
testRestTemplateForPostV2(restTemplate);
}
/**
* 方式一: 调用JSON的Post请求
* @param restTemplate 调用http请求
*/
private static void testRestTemplateForPostV1(RestTemplate restTemplate) {
// 1-1. 请求头信息
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
// 1-2. . 请求参数
JSONObject postParameters = new JSONObject();
// ParameterRo postParameters = new ParameterRo();
// Map<String, String> postParameters = new HashMap<>(3);
postParameters.put("openid", "opentid_test");
HttpEntity<JSONObject> requestEntity = new HttpEntity<>(postParameters, headers);
// 1-3. 请求地址
String url = "http://www.lala.com/projectPoth/saveIPAndAddress";
// 2-0. 调用
JSONObject exchange;
try {
exchange = restTemplate.postForObject(url, requestEntity, JSONObject.class);
LOGGER.info(exchange.toString());
System.out.println(exchange.toString());
} catch (RestClientException e) {
LOGGER.info("请求失败...");
System.out.println("请求失败: " + e.getMessage());
}
}
/**
* 方式二: 调用普通Post请求(简单版)
* text请求, json响应
* @param restTemplate 调用http请求
*/
private static void testRestTemplateForPostV2(RestTemplate restTemplate) {
// 1-1. . 请求参数
MultiValueMap<String, String> requestEntity = new LinkedMultiValueMap<>();
requestEntity.set("token", TOKEN);
// 1-2. 请求地址
String url = "http://www.lala.com/project/searchGroupOrgList";
// 2-0. 调用
JSONArray exchange;
try {
exchange = restTemplate.postForObject(url, requestEntity, JSONArray.class);
LOGGER.info(exchange.toString());
System.out.println(exchange.toString());
} catch (RestClientException e) {
LOGGER.info("请求失败...");
System.out.println("请求失败: " + e.getMessage());
}
}
/**
* 模拟请求参数
*/
static private class ResponseVo {
private String code = "0";
private String errMsg = "请求失败...";
private Object data;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getErrMsg() {
return errMsg;
}
public void setErrMsg(String errMsg) {
this.errMsg = errMsg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
}
附录二, httpClient参考网址
httpclient调用http请求学习: https://www.cnblogs.com/fengli9998/p/8028250.html
更多推荐
所有评论(0)