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面向切面 ...
随机推荐
- git强制push
Git 如何强制push? $ git push -u origin master –f 文章来源:刘俊涛的博客 地址:http://www.cnblogs.com/lovebing 欢迎关注,有 ...
- MyEclipse 2015利用Cygwin+CDT搭建C/C++开发环境
GitHub原文:https://github.com/x113773/testall/issues/22 首先安装Cygwin 1:首先去网站 www.cygwin.com 下载 Cygwin 的 ...
- Python核心编程笔记--动态属性
一.动态语言与静态语言 1.1 静态语言特点: a. 在定义变量时需要指定变量的类型,根据指定的类型来确定变量所占的内存空间 b. 需要经过编译才能运行 c. 在代码编译后,运行过程不能对代码进行操作 ...
- mysql字符串操作相关函数用法总结
功能用法简单例子一览表 函数 功能 用法 例子 left() 从字符串左边为边界返回相应长度的子字符串 left(str, length) mysql> select left('vssf',3 ...
- AIO5凭证性质设置接收下/上差(%),但是订单操作不起效。
问题: AIO5凭证性质设置接收下/上差(%),但是订单操作不起效. 例如: 现在采购订单下了200个,我想限制收货只能收两百以内. 在在线帮助上看到有接收下/上差(%)字段可以进行限制,但是在凭证性 ...
- 从mysql数据库取一条记录里的某个字段的值
<?php $link = mysqli_connect("localhost","root","root","dbname ...
- iOS开发证书和配置文件的使用
提示:之前只是根据网上的流程完成了iOS项目的发布过程,对于证书和配置文件仍是一头雾水,这里参照别人的文章,简单了解一下,毕竟以后用的着. 这里有几个问题: 什么是iOS证书,它是如何与app应用关联 ...
- deeplearning.ai 神经网络和深度学习 week1 深度学习概论 听课笔记
1. 预测房价.广告点击率:典型的神经网络,standard NN. 图像:卷积神经网络,CNN. 一维序列数据,如音频,翻译:循环神经网络,RNN. 无人驾驶,涉及到图像.雷达等更多的数据类型:混合 ...
- linux(二)之linux常用命令一
linux的命令非常之多,命令多就算了关键每个命令还有很多的参数.不过其实并不要去害怕它.你只要常去用,并且的话,大部分你只要记住命令,参数不记得我们可以去查帮助文档.加油吧!老帖们. 一.登入\登出 ...
- AtCoder Regular Contest 069 D
D - Menagerie Time limit : 2sec / Memory limit : 256MB Score : 500 points Problem Statement Snuke, w ...