Spring的RestTemplata使用
spring-web的RestTemplata是对java底层http的封装,使用RestTemplata用户可以不再关注底层的连接建立,并且RestTemplata不仅支持Rest规范,还可以定义返回值对象类型。
在使用中可以直接new一个RestTemplate对象,在我们创建的RestTemplate对象中会有一些返回消息的消息转换器,可以根据返回数据的MediaType寻找对应的转换器并进行MediaType转换。自己也可以创建消息转换器,创建一个类继承AbstractGenericHttpMessageConverter<T>类或者实现HttpMessageConverter<T>接口,需要注意的是canRead方法和canWrite方法最好自己做判断,在writeInternal或write方法中将参数写入到流,在readInternal或read方法中将返回结果从流的body中获取并进行类型映射。
RestTemplate对象在底层通过使用java.net包下的实现创建HTTP 请求,可以通过使用ClientHttpRequestFactory指定不同的HTTP请求方式。
ClientHttpRequestFactory接口主要提供了两种实现方式:
- 一种是SimpleClientHttpRequestFactory,使用J2SE提供的方式(既java.net包提供的方式)创建底层的Http请求连接。
- 一种方式是使用HttpComponentsClientHttpRequestFactory方式,底层使用HttpClient访问远程的Http服务,使用HttpClient可以配置连接池和证书等信息。
RestTemplate默认是使用SimpleClientHttpRequestFactory,内部是调用jdk的HttpConnection,默认超时为-1,我们可以自己定义超时时间
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
//设置连接超时,单位毫秒
factory.setConnectTimeout(5000);
//设置读取超时,单位毫秒
factory.setReadTimeout(10000);
RestTemplate restTemplate = new RestTemplate(factory);
使用GET请求:
String url = "http://localhost:80/mandy/login.json?account=123456&password=123456";
Result res = restTemplate.getForObject(url, Result.class);
RestTemplate源码:
@Override
public <T> T getForObject(String url, Class<T> responseType, Object... urlVariables) throws RestClientException {
RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);
HttpMessageConverterExtractor<T> responseExtractor =
new HttpMessageConverterExtractor<T>(responseType, getMessageConverters(), logger);
return execute(url, HttpMethod.GET, requestCallback, responseExtractor, urlVariables);
}
使用get请求直接将参数拼接到地址上最好,不知道什么原因如果使用第三个参数,即便是MultiValueMap类型也不行(网上有人说用MultiValueMap类型可以,我试了不行)
使用POST请求:
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("name", "测试");
map.put("account", "qwer");
map.put("password", "qwer");
ObjectMapper mapper = new ObjectMapper();
String jsonStr = null;
try {
jsonStr = mapper.writeValueAsString(map);
} catch (Exception e) {
e.printStackTrace();
}
//创建HTTP头部实体,填充头部信息,比如数据格式
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
//创建HTTP实体,可以直接利用构造方法将请求体和请求头放进去
HttpEntity<String> httpEntity = new HttpEntity<String>(jsonStr2, httpHeaders);
String url = "http://localhost:80/mandy/user_enable.json";
//调用方法进行请求
Result res2 = restTemplate.postForObject(url, httpEntity, Result.class);
RestTemplate源码:
@Override
public <T> T postForObject(String url, Object request, Class<T> responseType, Object... uriVariables)
throws RestClientException { RequestCallback requestCallback = httpEntityCallback(request, responseType);
HttpMessageConverterExtractor<T> responseExtractor =
new HttpMessageConverterExtractor<T>(responseType, getMessageConverters(), logger);
return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables);
}
使用PUT请求:
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("user_id", "1");
map.put("enable", 0);
ObjectMapper mapper = new ObjectMapper();
String jsonStr = null;
try {
jsonStr = mapper.writeValueAsString(map);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
//创建HTTP头部实体,填充头部信息,比如数据格式
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
//创建HTTP实体,可以直接利用构造方法将请求体和请求头放进去
HttpEntity<String> httpEntity = new HttpEntity<String>(jsonStr, httpHeaders);
String url = "http://localhost:80/mandy/user_enable.json";
restTemplate.put(url , httpEntity);
RestTemplate源码:
@Override
public void put(String url, Object request, Object... urlVariables) throws RestClientException {
RequestCallback requestCallback = httpEntityCallback(request);
execute(url, HttpMethod.PUT, requestCallback, null, urlVariables);
}
这个方法有个小的缺点就是没有请求结果的返回值,如果需要用到返回值,就不能用这个方法。
如果要使用delete类型的请求,RestTemplate的put方法的参数列中只有下面几种
@Override
public void delete(String url, Object... urlVariables) throws RestClientException {
execute(url, HttpMethod.DELETE, null, null, urlVariables);
} @Override
public void delete(String url, Map<String, ?> urlVariables) throws RestClientException {
execute(url, HttpMethod.DELETE, null, null, urlVariables);
} @Override
public void delete(URI url) throws RestClientException {
execute(url, HttpMethod.DELETE, null, null);
}
这些方法并没有给我们参数让我们放请求体内容,所以如果要直接使用RestTemplate提供的Delete方法,接口必须使用restful风格,将参数放在地址中,通过@PathVariable(value="")注解将参数获取到。
重点:其实我们可以直接使用RestTemplate的exchange方法,如下
@Override
public <T> ResponseEntity<T> exchange(String url, HttpMethod method,
HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables) throws RestClientException { RequestCallback requestCallback = httpEntityCallback(requestEntity, responseType);
ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType);
return execute(url, method, requestCallback, responseExtractor, uriVariables);
}
这里只列举了一个方法,其他的可以看源码,这个方法可以进行所有类型的请求。
在这个方法中,method参数可以通过HTTPMethod枚举来进行获取,requestEntity参数是自己封装的HttpEntity实体,包含请求体和请求头,responseType参数是返回结果的映射类,uriVariables这个参数给我的印象就是鸡肋(个人看法),获取请求返回接口可以通过方法返回值的getBody()方法获取。
============================================================================
请原谅我的无知,最近又研究了下spring的restTemplate类的方法,突然间发现uriVariables这个参数的用法,如下所示:
RestTemplate template = new RestTemplate();
Map result = template.getForObject("http://localhost:8080/login.json?account={param1}&password={param2}", Map.class, "123456", "654123");
HashMap<String, String> map = new HashMap<>();
map.put("param2", "654123");
map.put("param1", "123456");
Map result2 = template.getForObject("http://localhost:8080//login.json?account={param1}&password={parma2}", Map.class, map);
// result与result2的结果是一致的
在URL中我们可以先定义好需要拼接在URL中的参数以及将要被代替的参数(使用花括号进行包含),uriVariables参数如果使用可变数组的形式,要保证替换参数和将要被替换的参数顺序要一致,如果使用Map的形式,要保证被替代的参数名在传入的map中有相应的key,不然会在参数替换的抛出异常。
Spring的RestTemplata使用的更多相关文章
- 基于spring注解AOP的异常处理
一.前言 项目刚刚开发的时候,并没有做好充足的准备.开发到一定程度的时候才会想到还有一些问题没有解决.就比如今天我要说的一个问题:异常的处理.写程序的时候一般都会通过try...catch...fin ...
- 玩转spring boot——快速开始
开发环境: IED环境:Eclipse JDK版本:1.8 maven版本:3.3.9 一.创建一个spring boot的mcv web应用程序 打开Eclipse,新建Maven项目 选择quic ...
- Spring基于AOP的事务管理
Spring基于AOP的事务管理 事务 事务是一系列动作,这一系列动作综合在一起组成一个完整的工作单元,如果有任何一个动作执行失败,那么事务 ...
- [Spring]IoC容器之进击的注解
先啰嗦两句: 第一次在博客园使用markdown编辑,感觉渲染样式差强人意,还是github的样式比较顺眼. 概述 Spring2.5 引入了注解. 于是,一个问题产生了:使用注解方式注入 JavaB ...
- 学习AOP之透过Spring的Ioc理解Advisor
花了几天时间来学习Spring,突然明白一个问题,就是看书不能让人理解Spring,一方面要结合使用场景,另一方面要阅读源代码,这种方式理解起来事半功倍.那看书有什么用呢?主要还是扩展视野,毕竟书是别 ...
- 学习AOP之深入一点Spring Aop
上一篇<学习AOP之认识一下SpringAOP>中大体的了解了代理.动态代理及SpringAop的知识.因为写的篇幅长了点所以还是再写一篇吧.接下来开始深入一点Spring aop的一些实 ...
- 学习AOP之认识一下Spring AOP
心碎之事 要说知道AOP这个词倒是很久很久以前了,但是直到今天我也不敢说非常的理解它,其中的各种概念即抽象又太拗口. 在几次面试中都被问及AOP,但是真的没有答上来,或者都在面上,这给面试官的感觉就是 ...
- 为什么做java的web开发我们会使用struts2,springMVC和spring这样的框架?
今年我一直在思考web开发里的前后端分离的问题,到了现在也颇有点心得了,随着这个问题的深入,再加以现在公司很多web项目的控制层的技术框架由struts2迁移到springMVC,我突然有了一个新的疑 ...
- Spring之旅(2)
Spring简化Java的下一个理念:基于切面的声明式编程 3.应用切面 依赖注入的目的是让相互协作的组件保持松散耦合:而AOP编程允许你把遍布应用各处的功能分离出来形成可重用的组件. AOP面向切面 ...
随机推荐
- Sqlmap Tamper大全(1)
sqlmap是一个自动化的SQL注入工具,其主要功能是扫描,发现并利用给定的URL的SQL注入漏洞,目前支持的数据库是MS-SQL,,MYSQL,ORACLE和POSTGRESQL.SQLMAP采用四 ...
- MySQL优化五 SQL优化
1.减少 IO 次数 IO永远是数据库最容易瓶颈的地方,这是由数据库的职责所决定的,大部分数据库操作中超过90%的时间都是 IO 操作所占用的,减少 IO 次数是 SQL 优化中需要第一优先考虑,当然 ...
- [Micropython][ESP8266] TPYBoard V202 之MQTT协议接入OneNET云平台
随着移动互联网的发展,MQTT由于开放源代码,耗电量小等特点,将会在移动消息推送领域会有更多的贡献,在物联网领域,传感器与服务器的通信,信息的收集,MQTT都可以作为考虑的方案之一.在未来MQTT会进 ...
- 老铁,这年头不会点Git真不行!!!
版本控制 说到版本控制,脑海里总会浮现大学毕业是写毕业论文的场景,你电脑上的毕业论文一定出现过这番景象! 毕业论文_初稿.doc 毕业论文_修改1.doc 毕业论文_修改2.doc 毕业论文_修改3. ...
- commons -lang(2) RandomStringUtils RandomUtils
上一篇是StringUtils 链接http://www.cnblogs.com/tele-share/p/8060129.html 1.RandomStringUtils 1.1模拟实现random ...
- vmware 解决 authentication token manipulation error
vmvare虚拟机长时间未使用,导致再次登录的时候密码忘了,无法登录. 启动时长按shift,进入root(recovery)模式, (recovery mode),进入"Recovery ...
- tornado SSL 证书获取与服务器配置
转载注明出处: http://www.cnblogs.com/ityoung/p/8296088.html 自动化测试/持续集成/测试开发 QQ交流群: 70160503 服务端生成证书 进入 ope ...
- Zabbix实战-简易教程--技巧(本地化)
1.zabbix的logo图标替换(不建议修改) 3.0版本以下: 1.修改/usr/share/zabbix/include/page_header.php 2.修改/usr/share/zabbi ...
- Java面向对象抽象类案例分析
/** 雇员示例: 需求:公司中程序员有姓名,工号,薪水,工作内容 项目经理除了有姓名,工号,薪水还有奖金,工作内容 对给出需求进行数据建模 分析: 在这个问题领域中,先找出涉及的对象 通过名词提炼法 ...
- UVA - 10339-Watching Watches
10339 - Watching Watches Time limit: 3.000 seconds It has been said that a watch that is stopped kee ...