前言
由于架构改造,以及程序的通用性,现在工程所以基础数据CURD操作,以及基本业务逻辑,均采用Api形式。而调用Api的工程会对数据进行进一步的加工处理、以及错误异常的抛出。
现在描述一下RestTemplate的几个常用的用法。
Spring RestTempalte 示例
配置文件
按如下方式在springBasic.xml中添加RestTemplat的配置;
为了方便,可以将restTemplat在一个父类中初始化,所有使用restTemplat的类可以继承该父类
如下
输入 :
少量参数
String
Integer
boolean
多个参数
Map
Map<String,String>
Map<String,Integer>
Map<String,Object>
等等等
建议
输出:
和Api的返回值有关,一般为ModelMap,而ModelMap为json形式。
RestTemplate 常用方法手册
1. 无参数
a) /api/common/getlist.json
2. 少量参数
a) 参数在url中;api/muser/getUserInfo/${uid}.json
b) 需要传过去参数;
3. 多个参数
a) 手动将参数装入Map中,传过去。注:此时,Api中需要手动获取Map中参数,然后手动组装为对象。不建议此方法
b) 将参数为 对象 传给Api
i.直接使用Map<String,Objece>传对象; 注:此处需要使用getForObject/postForObject方法,同时在调用处需要手动将Object序列化为json形式 ;其次在向Api传参数时,参数也是以json方式传过去的。我们在接收参数的时候,需要手动将参数反序列化为对应的Object或者List<Object>; 此处需要注意:在反序列化时,有些类型可能不匹配、那么我们需要做一些字符转换器、放在Spring容器中,保证其字段转换。
4. 常用方法
1 restTemplate.getForObject(url, responseType);
url:请求的url
responseType:返回类型
示例:
Api代码
说明:
b) 根据Api信息可知,此方法不需要任何参数,直接访问即可;返回类型为ModelMap类型,一般为json数据;这时我们可以使用restTemplate.getForObject(url, responseType);方法获取数据,或者使用restTemplate.getForObject(url, responseType);方法获取数据。两种区别在这里不能很好体现,下面仔细讲解。
c)使用restTemplat代码示例
说明:
此为不带有任何参数的请求,返回类型根据Api中返回类型来定,String、boolean、int、json等等。
2.restTemplate.postForObject(url, request, responseType);
url:请求的url
request:传给Api的数据类型
responseType:Api返回的数据类型
Api示例
说明:
@PathVariable(value="uid"),因为此参数可以从url中取得,所以我们可以用@PathVariable标签解析url中参数值,(value="uid")代表将名字为uid的值解析出来付给uid这个变量,类型为Long;
当然我们这时候也可以在方法里面这样写:Long uid = requet.getParameter("uid");这是最传统的方式,适合少量参数;
也可以直接在方法头这么写public ModelMap getManageUserInfo(ModelMap modelMap, Long uid , HttpServletRequest request)
或者这么写public ModelMap getManageUserInfo(ModelMap modelMap, @RequestParam("uid",required="false")Long uid , HttpServletRequest request);这种写法是用@RequestParam标签代替了上面的Long uid = requet.getParameter("uid");同时,required = false代表,这个参数是非必须的,有没有都可以,不会出现nullPoint异常,这也是这个标签的一个优点。
但是以上这些都不是最好的,因为当参数很多事,我们一个个传之后继续解析是不是会被累死?或者我们要把Api方法中的方法头写的多么长呢?
所以我们因为以上方式,我们要 将参数整理为对象传过去 ,这样就可以避免以上问题。
注意: @ResponseBody这个标签代表要返回数据类型,一定不要忘记。
Api示例:
Api调用示例:
说明:
1.这几个方法说明使用restTemplate的返回类型和Api定义的类型有关;
2. 注意: @ResponseBody这个标签代表要返回数据类型,一定不要忘记。
3.假如Api中有声明请求方法为get/post,则,我们只能使用跟其对应的方法;
例如:testInt() 方法在Api中声明为get、则我们只能使用对应的get请求;
4.在有很多参数时,我们可以先把参数序列化为json形式,然后使用postForObject;然后将其参数拼装到url中, Student student1 = restTemplate.postForObject("http://localhost:8080/test/voReturn.json" + "?student=" + stu, entity, Student.class); ;我们在Api中拿到参数后反序列化为对应的Vo;
注意: 在反序列化过程中,我们会遇到有些字段为null无法转换的情况,所以这时最好写一个null的转换器。尤其类型为int时,无法自动处理此情况,那么可以借助转换器处理。
遇到问题:今天request.getPetemper("aa"),无法获取数据值,这个原因有待追查。
总结:
以上几个方法基本可以使用restTempalate进行工作了,后续会对原理,以及其他方法做出总结
由于架构改造,以及程序的通用性,现在工程所以基础数据CURD操作,以及基本业务逻辑,均采用Api形式。而调用Api的工程会对数据进行进一步的加工处理、以及错误异常的抛出。
现在描述一下RestTemplate的几个常用的用法。
Spring RestTempalte 示例
配置文件
按如下方式在springBasic.xml中添加RestTemplat的配置;
- <bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
- <property name="messageConverters">
- <list>
- <bean class="org.springframework.http.converter.FormHttpMessageConverter" />
- <bean
- class="org.springframework.http.converter.StringHttpMessageConverter" />
- <bean
- class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
- </list>
- </property>
- </bean>
为了方便,可以将restTemplat在一个父类中初始化,所有使用restTemplat的类可以继承该父类
如下
- public class BaseController {
- @Autowired
- protected
- RestTemplate restTemplate;
- }
输入 :
少量参数
String
Integer
boolean
多个参数
Map
Map<String,String>
Map<String,Integer>
Map<String,Object>
等等等
建议
输出:
和Api的返回值有关,一般为ModelMap,而ModelMap为json形式。
RestTemplate 常用方法手册
1. 无参数
a) /api/common/getlist.json
2. 少量参数
a) 参数在url中;api/muser/getUserInfo/${uid}.json
b) 需要传过去参数;
3. 多个参数
a) 手动将参数装入Map中,传过去。注:此时,Api中需要手动获取Map中参数,然后手动组装为对象。不建议此方法
b) 将参数为 对象 传给Api
i.直接使用Map<String,Objece>传对象; 注:此处需要使用getForObject/postForObject方法,同时在调用处需要手动将Object序列化为json形式 ;其次在向Api传参数时,参数也是以json方式传过去的。我们在接收参数的时候,需要手动将参数反序列化为对应的Object或者List<Object>; 此处需要注意:在反序列化时,有些类型可能不匹配、那么我们需要做一些字符转换器、放在Spring容器中,保证其字段转换。
4. 常用方法
1 restTemplate.getForObject(url, responseType);
url:请求的url
responseType:返回类型
示例:
Api代码
- /**
- * 获取数据)
- * @param modelMap
- * @return
- */
- @RequestMapping(value = "/getlist.json")
- @ResponseBody
- public ModelMap getCompanyList(ModelMap modelMap) {
- modelMap.clear();
- List<ShortCompanyVO> companyList = new ArrayList<ShortCompanyVO>();
- companyList = companyServiceImpl.getAllCompanyList();
- modelMap.put(WebApplicationConstant.FLAG_STATUS, AppConstant.JSON_RESPONSE_STATUS_SUCCESS);
- modelMap.put(WebApplicationConstant.FLAG_RESULT, companyList);
- log.debug(JsonUtil.map2json(modelMap));
- return modelMap;
- }
说明:
b) 根据Api信息可知,此方法不需要任何参数,直接访问即可;返回类型为ModelMap类型,一般为json数据;这时我们可以使用restTemplate.getForObject(url, responseType);方法获取数据,或者使用restTemplate.getForObject(url, responseType);方法获取数据。两种区别在这里不能很好体现,下面仔细讲解。
c)使用restTemplat代码示例
- public class TestTemplate {
- @Autowired
- protected RestTemplate restTemplate;
- @BeforeClass
- public static void setUpBeforeClass() throws Exception {
- }
- @Before
- public void setUp() throws Exception {
- }
- @Test
- public void test() {
- String string = restTemplate.getForObject("http://localhost:8080/api/common/getlist.json", String.class);
- System.out.print(string);
- }
- }
说明:
此为不带有任何参数的请求,返回类型根据Api中返回类型来定,String、boolean、int、json等等。
2.restTemplate.postForObject(url, request, responseType);
url:请求的url
request:传给Api的数据类型
responseType:Api返回的数据类型
Api示例
- /**
- * 获取用户信息
- * @param uid
- * @return
- */
- @RequestMapping(value="/getManageUserInfo/{uid}.json")
- @ResponseBody
- public ModelMap getManageUserInfo(ModelMap modelMap, [color=red]@PathVariable(value="uid") long uid[/color], HttpServletRequest request){
- try {
- if (uid <= 0) {
- modelMap.put("status", AppConstant.STATUS_REQUEST_ERROR);
- return modelMap;
- }
- AccountUser accountUser = manageAccountService.getManageUserInfo(uid);
- if (accountUser == null) {
- modelMap.put("status", AppConstant.STATUS_SYS_ERROR);
- return modelMap;
- }
- modelMap.put("status", AppConstant.STATUS_SUCCESS);
- modelMap.put("result", accountUser);
- } catch (Exception e) {
- e.printStackTrace();
- logger.error("getManageUserInfo is error " + e);
- modelMap.put("status", AppConstant.STATUS_SYS_ERROR);
- return modelMap;
- }
- return modelMap;
- }
说明:
@PathVariable(value="uid"),因为此参数可以从url中取得,所以我们可以用@PathVariable标签解析url中参数值,(value="uid")代表将名字为uid的值解析出来付给uid这个变量,类型为Long;
当然我们这时候也可以在方法里面这样写:Long uid = requet.getParameter("uid");这是最传统的方式,适合少量参数;
也可以直接在方法头这么写public ModelMap getManageUserInfo(ModelMap modelMap, Long uid , HttpServletRequest request)
或者这么写public ModelMap getManageUserInfo(ModelMap modelMap, @RequestParam("uid",required="false")Long uid , HttpServletRequest request);这种写法是用@RequestParam标签代替了上面的Long uid = requet.getParameter("uid");同时,required = false代表,这个参数是非必须的,有没有都可以,不会出现nullPoint异常,这也是这个标签的一个优点。
但是以上这些都不是最好的,因为当参数很多事,我们一个个传之后继续解析是不是会被累死?或者我们要把Api方法中的方法头写的多么长呢?
所以我们因为以上方式,我们要 将参数整理为对象传过去 ,这样就可以避免以上问题。
注意: @ResponseBody这个标签代表要返回数据类型,一定不要忘记。
Api示例:
- package com.bitbao.api.manage.controller;
- import javax.servlet.http.HttpServletRequest;
- import org.springframework.stereotype.Controller;
- import org.springframework.ui.ModelMap;
- import org.springframework.web.bind.annotation.PathVariable;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RequestMethod;
- import org.springframework.web.bind.annotation.ResponseBody;
- import com.bitbao.api.manage.bean.Student;
- /**
- * Test of RestTemplate
- * @author qiuying.huang
- * @since 2013-10-14
- */
- @RequestMapping("/test")
- @Controller
- public class TestRestTemplate {
- @RequestMapping(value = "/intResult/{param}.json" , method = RequestMethod.GET)
- @ResponseBody
- public int intResult(HttpServletRequest request,@PathVariable(value="param") int param){
- int a = request.getParameter("param") == null ? 0 : Integer.valueOf(request.getParameter("param"));
- int b = 100;
- System.out.println("request is " + a );
- int sum = b+param;
- return sum;
- }
- @RequestMapping(value = "/voReturn.json")
- @ResponseBody
- public Student voReturn(Student student){
- return student;
- }
- @RequestMapping(value = "/mapReturn.json")
- @ResponseBody
- public ModelMap mapReturn(ModelMap modelMap){
- Student student = new Student();
- student.setName("wang想");
- modelMap.put("status", 0);
- modelMap.put("student", student);
- return modelMap;
- }
- }
Api调用示例:
- import java.util.Map;
- import org.junit.Before;
- import org.junit.BeforeClass;
- import org.junit.Test;
- import org.junit.runner.RunWith;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.http.HttpEntity;
- import org.springframework.test.context.ContextConfiguration;
- import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
- import org.springframework.util.LinkedMultiValueMap;
- import org.springframework.util.MultiValueMap;
- import org.springframework.web.client.RestTemplate;
- import com.bitbao.manager.bean.Student;
- import com.bitbao.manager.util.JsonUtil;
- @RunWith(SpringJUnit4ClassRunner.class)
- @ContextConfiguration(locations={"classpath:spring/root.xml","classpath:spring/dataSource.xml"})
- public class TestTemplate{
- @Autowired
- protected RestTemplate restTemplate;
- @BeforeClass
- public static void setUpBeforeClass() throws Exception {
- String url = "";
- }
- @Before
- public void setUp() throws Exception {
- }
- @Test
- /**
- * 返回Integer、int类型数据
- */
- public void testInt() {
- MultiValueMap<String,Object> dataMap = new LinkedMultiValueMap<String, Object>();
- int param = 22;
- dataMap.add("param", "23");
- HttpEntity<Object> entity = new HttpEntity<Object>(dataMap);
- Integer a = restTemplate.getForObject("http://localhost:8080/test/intResult/" + param + ".json" , Integer.class);//
- Integer b = restTemplate.getForObject("http://localhost:8080/test/intResult/" + param + ".json" , Integer.class);
- Integer c = restTemplate.getForObject("http://localhost:8080/test/intResult/" + param + ".json",Integer.class, entity);
- Integer d = restTemplate.postForObject("http://localhost:8080/test/intResult/" + param + ".json", entity, Integer.class);//此处会报错,因为Api中已经将此访问强制定位为get请求,所以只能使用get请求的方法。
- System.out.println("testInt a is : " + a);
- System.out.println("testInt b is : " + b);
- System.out.println("testInt c is : " + c);
- System.out.println("testInt d is : " + d);
- }
- // @Test
- // public void testString(){
- // Student student = new Student();
- // student.setAge(10);
- // student.setName("sdf");
- // MultiValueMap<String,String> dataMap = new LinkedMultiValueMap<String, String>();
- // String stu = JsonUtil.bean2json(student);
- // dataMap.add("student", stu);
- // HttpEntity<Object> entity = new HttpEntity<Object>(dataMap);
- Student student1 = restTemplate.getForObject("http://localhost:8080/test/voReturn.json", Student.class, entity);
- // Student student1 = restTemplate.postForObject("http://localhost:8080/test/voReturn.json", entity, Student.class);
- Student student2 = restTemplate.postForObject("http://localhost:8080/test/voReturn.json", stu, Student.class);
- // System.out.println("testString student1 is :" + student1 );
- // }
- /**
- * 返回String、Object数据
- */
- @Test
- public void testString(){
- Student student = new Student();
- student.setAge(10);
- student.setName("sdf");
- student.setBanji(123);
- MultiValueMap<String,String> dataMap = new LinkedMultiValueMap<String, String>();
- String stu = JsonUtil.bean2json(student);
- System.out.println("stu is " + stu);
- dataMap.add("student", stu);
- HttpEntity<Object> entity = new HttpEntity<Object>(dataMap);
- Student student1 = restTemplate.postForObject("http://localhost:8080/test/voReturn.json" + "?student=" + stu, entity, Student.class);
- System.out.println("testString student1 is :" + student1 );
- }
- /**
- * 返回Map数据
- */
- @Test
- public void testMap(){
- Map<String, Object> map1 = restTemplate.getForObject("http://localhost:8080/test/mapReturn.json" , Map.class);
- Map<String, Object> map2 = restTemplate.postForObject("http://localhost:8080/test/mapReturn.json", "", Map.class);//此处不需要参数,但是postForObject方法需要参数,所以穿了个"";这段建议使用get方法
- System.out.println("testMap map1 is :" + map1);
- System.out.println("testMap map2 is :" + map2);
- }
- }
说明:
1.这几个方法说明使用restTemplate的返回类型和Api定义的类型有关;
2. 注意: @ResponseBody这个标签代表要返回数据类型,一定不要忘记。
3.假如Api中有声明请求方法为get/post,则,我们只能使用跟其对应的方法;
例如:testInt() 方法在Api中声明为get、则我们只能使用对应的get请求;
4.在有很多参数时,我们可以先把参数序列化为json形式,然后使用postForObject;然后将其参数拼装到url中, Student student1 = restTemplate.postForObject("http://localhost:8080/test/voReturn.json" + "?student=" + stu, entity, Student.class); ;我们在Api中拿到参数后反序列化为对应的Vo;
注意: 在反序列化过程中,我们会遇到有些字段为null无法转换的情况,所以这时最好写一个null的转换器。尤其类型为int时,无法自动处理此情况,那么可以借助转换器处理。
遇到问题:今天request.getPetemper("aa"),无法获取数据值,这个原因有待追查。
总结:
以上几个方法基本可以使用restTempalate进行工作了,后续会对原理,以及其他方法做出总结