在REST接口的设计中,利用RestTemplate进行接口测试是种常见的方法。本文主要从以下四个方面来看RestTemplate的使用:

  • GET请求
  • POST请求
  • PUT请求
  • DELETE请求

OK,开始吧。

1. 用exchange方法提交

exchange既可以执行POST方法,还可以执行GET,设置header,所以应用最为广泛。

/*** 发送GET请求** @param uri* @param params* @param headers* @return*/
public Object doGet(String uri, Map<String, String> params, HttpHeaders headers) {HttpEntity<Object> entity = new HttpEntity<>(params, headers);return restTemplate.exchange(uri, HttpMethod.GET, entity, Object.class);
}public Object doPost(String uri, String token, Map<String, Object> params) {HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON_UTF8);headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);headers.add(AUTHORIZATION, "Bearer " + token);HttpEntity<Object> entity = new HttpEntity<>(params, headers);return restTemplate.exchange(uri, HttpMethod.POST, entity, Object.class);
}

2. 用postForEntity进行提交

//  上面的代码完全一样仅需替换exchange方法
ResponseEntity<String> response = client.postForEntity(url, requestEntity , String.class );Map<String, String> map = new HashMap<>();
map.put("name", "李四");
ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://HELLO-SERVICE/sayhello?name={name}", String.class, map);
return responseEntity.getBody();
  • 也可以前面使用name={name}这种形式,最后一个参数是一个map,map的key即为前边占位符的名字,map的value为参数值
  • getForEntity第二个参数String.class表示我希望返回的body类型是String

2.1 postForObject

HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
headers.add("Authorization", "Bearer " + token);
HttpEntity<Object> entity = new HttpEntity<>(params, headers);
Object responseEntity = client.postForObject(uri, entity, Object.class);

3.PUT请求

在RestTemplate中,PUT请求可以通过put方法调用,put方法的参数和前面介绍的postForEntity方法的参数基本一致,只是put方法没有返回值而已。举一个简单的例子,如下

Book book = new Book();
book.setName("红楼梦");
restTemplate.put("http://HELLO-SERVICE/getbook3/{1}", book, 99);

4.DELETE请求

delete请求我们可以通过delete方法调用来实现,如下例子:

restTemplate.delete("http://HELLO-SERVICE/getbook4/{1}", 100);

RestTemplate能大幅简化了提交表单数据的难度,并且附带了自动转换JSON数据的功能

JSONObject param = new JSONObject();
param.put("message", '短信内容');
JSONObject item = new JSONObject();
item.put("user_mobile", mobile);
item.put("signature", "短信签名");
param.put("sms", item);HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<JSONObject> requestEntity = new HttpEntity<JSONObject>(param, headers);
log.info("调用发送短信通知失败接口,requestEntity:{}", requestEntity);
ResponseEntity<JSONObject> responseEntity = restTemplate.exchange("http://notification.test.com", HttpMethod.POST, requestEntity, JSONObject.class);
JSONObject retJson = responseEntity.getBody();
log.info("调用发送短信通知接口,返回:{}", retJson);
Integer code = (Integer) retJson.get("code");
String msg = (String) retJson.get("message");
if (code > 0) {throw new BaseException("调用发送短信通知失败,原因:", msg);
}

5. HttpEntity与uriVariables

在RestTemplate的使用中,HttpEntity用于传递具体的参数值,而uriVariables则用于格式化Http地址,而不是地址参数,正确的用法如下:

//  在地址中加入格式化参数path
String url = "http://localhost/mirana-ee/app/{path}";
//  准备格式化参数
Map<String, String> varParams = new HashMap();
varParams.put("path", "login");
//  其他代码略
//  格式化提交地址
ResponseEntity<String> response = client.postForEntity(url, requestEntity , String.class, varParams);

6. 关于HttpMessageConverter的说明

在网上的很多例子中,我发现很多人为了处理Payload提交,都添加了自定义的HttpMessageConverter,如下

//  完全没有必要
client.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
client.getMessageConverters().add(new StringHttpMessageConverter());

然后,经过我查看源码与调试发现,RestTemplate内置了7种HttpMessageConverter,如下:

  1. org.springframework.http.converter.ByteArrayHttpMessageConverter
  2. org.springframework.http.converter.StringHttpMessageConverter
  3. org.springframework.http.converter.ResourceHttpMessageConverter
  4. org.springframework.http.converter.xml.SourceHttpMessageConverter
  5. org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter
  6. org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter
  7. org.springframework.http.converter.json.MappingJackson2HttpMessageConverter

7. 关于表单提交与Payload提交的差异

当POST请求的请求头里设置Content-Type: application/x-www-form-urlencoded(默认), 参数在请求体以标准的Form Data的形式提交,以&符号拼接,参数格式为key=value&key=value&key=value…. 
如果使用AJAX原生POST请求,请求头里设置Content-Type:application/json,请求的参数会显示在Request Payload中,参数格式为JSON格式:{“key”:”value”,”key”:”value”…},这种方式可读性会更好。对于Payload方式,提交的内容一定要是String,且Header要设置为“application/json”,示例如下:

//  请求地址
String url = "http://localhost/mirana-ee/app/login";
RestTemplate client = new RestTemplate();
//  一定要设置header
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
//  将提交的数据转换为String
//  最好通过bean注入的方式获取ObjectMapper
ObjectMapper mapper = new ObjectMapper();
Map<String, String> params= new HashMap();
params.put("username", "国米");
params.put("password", "123456");
String value = mapper.writeValueAsString(params);
HttpEntity<String> requestEntity = new HttpEntity<String>(value, headers);
//  执行HTTP请求
ResponseEntity<String> response = client.postForEntity(url, requestEntity , String.class );
System.out.println(response.getBody());

8.超时时间设置

SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setConnectTimeout(30 * 1000);
requestFactory.setReadTimeout(30 * 1000);
restTemplate.setRequestFactory(requestFactory);

不依赖第三方库的请求类

package net.demo.my.common.util;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;public class HttpUtil {public static final String APPLICATION_JSON = "application/json";public static final String APPLICATION_JSON_UTF8 = "application/json;charset=UTF-8";/*** Send a get request** @param url* @return response* @throws IOException*/static public String get(String url) throws IOException {return get(url, null);}/*** Send a get request** @param url     Url as string* @param headers Optional map with headers* @return response   Response as string* @throws IOException*/static public String get(String url,Map<String, String> headers) throws IOException {return fetch("GET", url, null, headers);}/*** Send a post request** @param url     Url as string* @param body    Request body as string* @param headers Optional map with headers* @return response   Response as string* @throws IOException*/static public String post(String url, String body,Map<String, String> headers) throws IOException {return fetch("POST", url, body, headers);}/*** Send a post request** @param url  Url as string* @param body Request body as string* @return response   Response as string* @throws IOException*/static public String post(String url, String body) throws IOException {return post(url, body, null);}/*** Post a form with parameters** @param url    Url as string* @param params map with parameters/values* @return response   Response as string* @throws IOException*/static public String postForm(String url, Map<String, String> params)throws IOException {return postForm(url, params, null);}/*** Post a form with parameters** @param url     Url as string* @param params  Map with parameters/values* @param headers Optional map with headers* @return response   Response as string* @throws IOException*/static public String postForm(String url, Map<String, String> params,Map<String, String> headers) throws IOException {// set content typeif (headers == null) {headers = new HashMap<String, String>();}headers.put("Content-Type", "application/x-www-form-urlencoded");// parse paramet  ersString body = "";if (params != null) {boolean first = true;for (String param : params.keySet()) {if (first) {first = false;} else {body += "&";}String value = params.get(param);body += URLEncoder.encode(param, "UTF-8") + "=";body += URLEncoder.encode(value, "UTF-8");}}return post(url, body, headers);}/*** Send a put request** @param url     Url as string* @param body    Request body as string* @param headers Optional map with headers* @return response   Response as string* @throws IOException*/static public String put(String url, String body,Map<String, String> headers) throws IOException {return fetch("PUT", url, body, headers);}/*** Send a put request** @param url Url as string* @return response   Response as string* @throws IOException*/static public String put(String url, String body) throws IOException {return put(url, body, null);}/*** Send a delete request** @param url     Url as string* @param headers Optional map with headers* @return response   Response as string* @throws IOException*/static public String delete(String url,Map<String, String> headers) throws IOException {return fetch("DELETE", url, null, headers);}/*** Send a delete request** @param url Url as string* @return response   Response as string* @throws IOException*/static public String delete(String url) throws IOException {return delete(url, null);}/*** Append query parameters to given url** @param url    Url as string* @param params Map with query parameters* @return url        Url with query parameters appended* @throws IOException*/static public String appendQueryParams(String url,Map<String, String> params) throws IOException {String fullUrl = url;if (params != null) {boolean first = (fullUrl.indexOf('?') == -1);for (String param : params.keySet()) {if (first) {fullUrl += '?';first = false;} else {fullUrl += '&';}String value = params.get(param);fullUrl += URLEncoder.encode(param, "UTF-8") + '=';fullUrl += URLEncoder.encode(value, "UTF-8");}}return fullUrl;}/*** Retrieve the query parameters from given url** @param url Url containing query parameters* @return params     Map with query parameters* @throws IOException*/static public Map<String, String> getQueryParams(String url)throws IOException {Map<String, String> params = new HashMap<String, String>();int start = url.indexOf('?');while (start != -1) {// read parameter nameint equals = url.indexOf('=', start);String param = "";if (equals != -1) {param = url.substring(start + 1, equals);} else {param = url.substring(start + 1);}// read parameter valueString value = "";if (equals != -1) {start = url.indexOf('&', equals);if (start != -1) {value = url.substring(equals + 1, start);} else {value = url.substring(equals + 1);}}params.put(URLDecoder.decode(param, "UTF-8"),URLDecoder.decode(value, "UTF-8"));}return params;}/*** Returns the url without query parameters** @param url Url containing query parameters* @return url        Url without query parameters* @throws IOException*/static public String removeQueryParams(String url)throws IOException {int q = url.indexOf('?');if (q != -1) {return url.substring(0, q);} else {return url;}}/*** Send a request** @param method  HTTP method, for example "GET" or "POST"* @param url     Url as string* @param body    Request body as string* @param headers Optional map with headers* @return response   Response as string* @throws IOException*/static public String fetch(String method, String url, String body,Map<String, String> headers) throws IOException {// connectionURL u = new URL(url);HttpURLConnection conn = (HttpURLConnection) u.openConnection();conn.setConnectTimeout(10000);conn.setReadTimeout(10000);// methodif (method != null) {conn.setRequestMethod(method);}// headersif (headers != null) {for (String key : headers.keySet()) {conn.addRequestProperty(key, headers.get(key));}}// bodyif (body != null) {conn.setDoOutput(true);OutputStream os = conn.getOutputStream();os.write(body.getBytes());os.flush();os.close();}// responseInputStream is = conn.getInputStream();String response = streamToString(is);is.close();// handle redirectsif (conn.getResponseCode() == 301) {String location = conn.getHeaderField("Location");return fetch(method, location, body, headers);}return response;}/*** Read an input stream into a string** @param in* @return* @throws IOException*/static public String streamToString(InputStream in) throws IOException {StringBuffer out = new StringBuffer();byte[] b = new byte[4096];for (int n; (n = in.read(b)) != -1; ) {out.append(new String(b, 0, n));}return out.toString();}
}

调用例子:

String url = "https://tcc.taobao.com/cc/json/mobile_tel_segment.htm";
Map<String, String> param = new HashMap<>();
param.put("tel", mobileNum);
String fullUrl = HttpUtil.appendQueryParams(url, param);
String res = HttpUtil.get(fullUrl);Map<String, String> headers = new HashMap<>();
headers.put("content-type", HttpUtil.APPLICATION_JSON_UTF8);
Map<String, String> param = new HashMap<>();
param.put("dataId", called);
String body = JSON.toJSONString(param);
String retJson = HttpUtil.post(url, body, headers);

基于RestTemplate的封装类

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;@Component
@Slf4j
public class HttpClientService {public static final String AUTHORIZATION = "Authorization";@Autowiredprivate RestTemplate customRestTemplate;public <T> T doPost(final String uri, final Map<String, Object> params, Class<T> cls, String token) {if (log.isInfoEnabled()) {log.info("请求 URL:" + uri);log.info("请求参数:" + JSON.toJSONString(params));}final HttpHeaders headers = new HttpHeaders();headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE);headers.add("keepalive_timeout", "30s");final HttpEntity<Map<String, Object>> entity = new HttpEntity<>(params, headers);return customRestTemplate.postForObject(uri, entity, cls);}public <T> T doPostUrlencoded(final String uri, final MultiValueMap<String, Object> params, Class<T> cls, String token) {if (log.isInfoEnabled()) {log.info("请求 URL:" + uri);log.info("请求参数:" + JSON.toJSONString(params));}final HttpHeaders headers = new HttpHeaders();headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE);headers.add("keepalive_timeout", "30s");final HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<>(params, headers);return customRestTemplate.postForObject(uri, entity, cls);}public <T> T doFormDataPost(final String uri, final Object params, Class<T> cls, String token) {if (log.isInfoEnabled()) {log.info("请求 URL:" + uri);log.info("请求参数:" + JSON.toJSONString(params));}final HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.MULTIPART_FORM_DATA);final HttpEntity<Object> entity = new HttpEntity<>(params, headers);return customRestTemplate.postForObject(uri, entity, cls);}public <T> T doPostByToken(final String uri, final Object params, Class<T> cls, String token) {if (log.isInfoEnabled()) {log.info("请求 URL:" + uri);log.info("请求参数:" + JSON.toJSONString(params));}final HttpHeaders headers = new HttpHeaders();headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);headers.add(AUTHORIZATION, "Bearer " + token);final HttpEntity<Object> entity = new HttpEntity<>(params, headers);return customRestTemplate.postForObject(uri, entity, cls);}public <T> T doPatchByToken(final String uri, final Object params, Class<T> cls, String token) {if (log.isInfoEnabled()) {log.info("请求 URL:" + uri);log.info("请求参数:" + JSON.toJSONString(params));}final HttpHeaders headers = new HttpHeaders();headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);headers.add(AUTHORIZATION, "Bearer " + token);final HttpEntity<Object> entity = new HttpEntity<>(params, headers);return customRestTemplate.patchForObject(uri, entity, cls);}public <T> T doDeleteByToken(final String uri, final Object params, Class<T> cls, String token) {if (log.isInfoEnabled()) {log.info("请求 URL:" + uri);log.info("请求参数:" + JSON.toJSONString(params));}final HttpHeaders headers = new HttpHeaders();headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);headers.add(AUTHORIZATION, "Bearer " + token);final HttpEntity<Object> entity = new HttpEntity<>(params, headers);ResponseEntity<T> resultEntity = customRestTemplate.exchange(uri, HttpMethod.DELETE, entity, cls);return resultEntity.getBody();}public <T> T doGet(final String uri, final Map<String, Object> params, Class<T> cls) {final StringBuilder uriBuilder = new StringBuilder(uri);if (!uri.contains("?")) {uriBuilder.append("?");}uriBuilder.append("t=").append(System.currentTimeMillis());if (MapUtils.isNotEmpty(params)) {params.forEach((key, value) -> {uriBuilder.append("&");uriBuilder.append(key).append("=");try {uriBuilder.append(URLEncoder.encode(String.valueOf(value), "UTF-8"));} catch (UnsupportedEncodingException e) {log.info(e.getCause().getMessage());}});}if (log.isInfoEnabled()) {log.info("请求 URL:" + uriBuilder.toString());}return customRestTemplate.getForObject(uriBuilder.toString(), cls);}public <T> T doGet(final String uri, String param, Class<T> cls) {final String url = uri + "/" + param;if (log.isInfoEnabled()) {log.info("请求 URL:" + url);}return customRestTemplate.getForObject(url, cls);}public <T> T doGet(final String uri, Class<T> cls) {if (log.isInfoEnabled()) {log.info("请求 URL:" + uri);}return customRestTemplate.getForObject(uri, cls);}
}

Java RestTemplate中几种常见的请求方式相关推荐

  1. Spring RestTemplate中几种常见的请求方式GET请求 POST请求 PUT请求 DELETE请求

    Spring RestTemplate中几种常见的请求方式 原文地址: https://blog.csdn.net/u012702547/article/details/77917939 版权声明:本 ...

  2. Spring RestTemplate中几种常见的请求方式

    关注公众号[江南一点雨],专注于 Spring Boot+微服务以及前后端分离等全栈技术,定期视频教程分享,关注后回复 Java ,领取松哥为你精心准备的 Java 干货! 在Spring Cloud ...

  3. unity3d中画线有几种方式_Spring RestTemplate中几种常见的请求方式

    原文 https://segmentfault.com/a/1190000011093597 在Spring Cloud中服务的发现与消费一文中,当我们从服务消费端去调用服务提供者的服务的时候,使用了 ...

  4. SpringCloud之RestTemplate,几种常见的请求方式

    https://github.com/lenve/SimpleSpringCloud/tree/master/RestTemplate在Spring Cloud中服务的发现与消费一文中,当我们从服务消 ...

  5. Mysql中4种常见的插入方式

    4种常见insert方式 准备工作 CREATE TABLE `identity_table` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id' ...

  6. JAVA数组中五种常见排序方法

    前言: 几种常用的JAVA数组排序方法的整合. 法一:Arrays.sort() Arrays.sort()排序方法在java中是最简单且最常用的排序方法 int []arr1= {45,34,59, ...

  7. JavaScript中6种常见的继承方式

    为什么需要继承? 在实际编码的过程中,如果有很多类似的方法都存放于构造函数中,这样会导致内存的浪费(内存泄漏),在这种情况下我们就需要用到继承. 继承是什么? 所谓继承就是通过某种方式让一个对象可以访 ...

  8. java获取项目中的路径_java中几种获取项目路径方式

    转自http://caodaoxi.iteye.com/blog/1234805 在jsp和class文件中调用的相对路径不同. 在jsp里,根目录是WebRoot 在class文件中,根目录是Web ...

  9. java简述常见的布局极其特点_请简要说明 Android 中五种常见布局的特点。_学小易找答案...

    [简答题]请简要说明有序广播和无序广播的区别 [简答题]请简要说明 Android 程序结构中 AndroidManifest.xml 的功能? [简答题]简述李村站人工办理进路的作业过程. [简答题 ...

最新文章

  1. Qt中的QWidget
  2. Linux课程笔记 Crond介绍
  3. Razor语法和Razor引擎大全
  4. 计算机专业论文设计与实现,计算机专业论文 计算机网络的设计与实现.doc
  5. 十分钟学习python_10分钟带你入门Cython
  6. Zookeeper安装,Zookeeper单机模式安装
  7. CentOS下MySQL安装后配置和设置
  8. Layui 表格渲染
  9. thinkphp 又一问题
  10. linux 卸载 java_Linux安装卸载JDK完整步骤
  11. 时间序列数据的特征提取
  12. 打印机计算机故障或繁忙,联想打印机繁忙是怎么回事?
  13. 计算机毕业设计-springboot协同办公管理系统-公文流转系统代码设计-多人协同办公讨论管理系统
  14. 近红外光谱定性定量分析模型 Matlab
  15. 世界你好python_Python基础01之“你好世界”
  16. Java 验证身份证号码
  17. 上海php程序员职友集,好程序员WEB前端培训|HTML5培训|H5培训-好程序员官网
  18. GDUT 第一次组队赛 Team up! Team up! Team up!(三,dp,dfs)
  19. sql统计各科成绩大于平均分的人_数据分析师SQL面试必备50题
  20. “狗屁不通文章生成器”项目登顶GitHub热榜~

热门文章

  1. MATLAB/ArcGIS读取nc数据并进行可视化
  2. 用python玩转数据作业答案_大学mooc2020年用Python玩转数据作业答案
  3. 产品设计公司的头脑风暴是什么?
  4. 【每日一练】小米搜索框
  5. 计算机毕业设计SSMjava高校社团管理系统【附源码数据库】
  6. git教程(涵盖GitHub\Gitee\Gitlab)
  7. ☆苹果MAC OS X ★ 安装双系统☆
  8. matlab 圆角,rectangle函数MATLAB matlab中rectangle画圆角矩形
  9. Statspack 基础入门
  10. 计算机键盘手指放置,[转载]键盘上手指放置的位置图