Spring RestTemplate中常见的请求方式

1.基本概念

Spring RestTemplate 是 Spring 提供的用于访问 Rest 服务的客户端,RestTemplate 提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率,所以很多客户端比如 Android或者第三方服务商都是使用 RestTemplate 请求 restful 服务

借助 RestTemplate,Spring应用能够方便地使用REST资源 .Spring的 RestTemplate访问使用了模版方法的设计模式.

2.Spring 中如何使用Rest资源

RestTemplate中定义了11个独立的方法,分别是:

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

其中前十个方法分别有三个重载形式,以getForObject为例:第一个参数是接口的url,第二个参数是接收的返回值的类型,第三个是你要传的参数,可以为多个Object对象,也可以是一个Map .而返回类型则是传入第二个参数对应的类型.

 <T> T getForObject(String var1, Class<T> var2, Object... var3) throws RestClientException;

 <T> T getForObject(String var1, Class<T> var2, Map<String, ?> var3) throws RestClientException;

 <T> T getForObject(URI var1, Class<T> var2) throws RestClientException;

而最后一个exchange方法有8个重载形式,你可以自由的组装REST调用方法,而返回的结果都是响应体所映射成的对象-ResponseEntity:

 <T> ResponseEntity<T> exchange(String var1, HttpMethod var2, HttpEntity<?> var3, Class<T> var4, Object... var5) throws RestClientException;

    <T> ResponseEntity<T> exchange(String var1, HttpMethod var2, HttpEntity<?> var3, Class<T> var4, Map<String, ?> var5) throws RestClientException;

    <T> ResponseEntity<T> exchange(URI var1, HttpMethod var2, HttpEntity<?> var3, Class<T> var4) throws RestClientException;

    <T> ResponseEntity<T> exchange(String var1, HttpMethod var2, HttpEntity<?> var3, ParameterizedTypeReference<T> var4, Object... var5) throws RestClientException;

    <T> ResponseEntity<T> exchange(String var1, HttpMethod var2, HttpEntity<?> var3, ParameterizedTypeReference<T> var4, Map<String, ?> var5) throws RestClientException;

    <T> ResponseEntity<T> exchange(URI var1, HttpMethod var2, HttpEntity<?> var3, ParameterizedTypeReference<T> var4) throws RestClientException;

    <T> ResponseEntity<T> exchange(RequestEntity<?> var1, Class<T> var2) throws RestClientException;

    <T> ResponseEntity<T> exchange(RequestEntity<?> var1, ParameterizedTypeReference<T> var2) throws RestClientException;

其中ResponseEntity对象继承于HttpEntity ,在HttpEntity的基础上又封装了一个HttpStatus属性 .

这样如果返回ResponseEntity对象的话,我们可以拿到所有的关于请求的信息,包括了 请求头,请求状态 ,和请求体的信息.如:

实例:

接口提供方:

接口调用 :

@Service
@Transactional
public class XXXServiceImpl implements XXXService{



	@Autowired
	private XXXMapper mapper;
	@Autowired
	private RestTemplate restTemplate;


	private final static Logger logger = LoggerFactory.getLogger(XXXServiceImpl.class);


	@Value(value = "${esb.product.url}")
	private String  url;
	@Value(value = "${esb.product.username}")
	private  String  username;
	@Value(value = "${esb.product.password}")
	private  String  password;


	/**
	 * @Author younus
	 * @Description // 调用接口
	 * @Param
	 **/
	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public void getEsbProductMultiples() {
		HttpHeaders headers = createHeaders(username, password);
		HttpEntity requestWithBasicAuth = new HttpEntity(headers);
		//接口返回的数据
		EsbProductMultiple datas= restTemplate.postForObject(url, requestWithBasicAuth, EsbProductMultiple.class);
		List<PubProductMutiple> pubProductMutiples=datas.getProductMutiples();
		if (pubProductMutiples != null && !pubProductMutiples.isEmpty()&& "S".equals(datas.getRetStatus())){
			//生成批次号
			String uuid= UUID.randomUUID().toString().replaceAll("-","");
			//具体业务逻辑
            
			}
		
	logger.info("-----------------------接口调用完成------------------------");
		}

	}

//模拟头信息
	private HttpHeaders createHeaders(String username, String password){
		return new HttpHeaders() {{
			String auth = username + ":" + password;
			byte[] encodedAuth = Base64.encodeBase64(
					auth.getBytes(Charset.forName("US-ASCII")) );
			String authHeader = "Basic " + new String( encodedAuth );
			set( "Authorization", authHeader );
		}};
	}
}

可以看到调用postForObject()会将结果封装为我们自定义的对象.

excute方法

所有的get、post、delete、put、options、head、exchange方法最终调用的都是excute()方法,excute()方法只是将String格式的URI转成了java.net.URI,之后调用了doExecute方法。举个栗子:

public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> urlVariables) throws RestClientException {
        RequestCallback requestCallback = this.acceptHeaderRequestCallback(responseType);
        ResponseExtractor<ResponseEntity<T>> responseExtractor = this.responseEntityExtractor(responseType);
        return (ResponseEntity)this.execute(url, HttpMethod.GET, requestCallback, responseExtractor, urlVariables);
    }

调用过程:

execute方法:

 public <T> T execute(String url, HttpMethod method, RequestCallback requestCallback, ResponseExtractor<T> responseExtractor, Object... urlVariables) throws RestClientException {
        URI expanded = this.getUriTemplateHandler().expand(url, urlVariables);
        return this.doExecute(expanded, method, requestCallback, responseExtractor);
    }

猜你喜欢

转载自blog.csdn.net/weixin_38158701/article/details/84819814