`
yu_duo
  • 浏览: 56355 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

Spring restTemplat 常用基本用法总结

阅读更多
前言

由于架构改造,以及程序的通用性,现在工程所以基础数据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进行工作了,后续会对原理,以及其他方法做出总结。

分享到:
评论
1 楼 潘荣甫 2016-12-15  
怒赞博主..

相关推荐

    使用spring环境常用jar

    本篇将详细介绍标题“使用spring环境常用jar”所涵盖的关键知识点。 1. **Spring IOC(Inversion of Control)**:Spring的IOC容器负责创建对象、管理对象之间的关系,它将对象的创建和维护权交给了框架,从而降低...

    spring最常用jar包

    标题 "spring最常用jar包" 暗示了我们讨论的核心是Spring框架中不可或缺的库文件,这些jar包是开发人员在使用Spring进行Java应用程序开发时最常引用的基础组件。Spring是一个开源的Java平台,它提供了全面的企业级...

    Spring JdbcTemplate 常用方法整理

    本文将深入探讨Spring JdbcTemplate的常用方法,并结合提供的`JsonBean.java`和`JdbcUtils.java`文件,来理解其在实际应用中的使用。 首先,JdbcTemplate的核心功能在于它提供了一系列的方法来执行SQL语句,包括...

    Spring中常用注解

    本文将深入探讨Spring框架中的一些常用注解,并通过实例来解析它们的工作原理。 1. `@Component`: 这是Spring中的基础组件注解,它标记一个类为Spring容器管理的bean。当你在类上使用`@Component`时,Spring会自动...

    spring常用jar包

    在这个名为"spring常用jar包"的压缩包中,包含了一些Spring框架运行所必需的核心库。下面我们将逐一解析这些jar包的功能和重要性。 1. aspectjrt.jar:这是AspectJ运行时库,用于支持面向切面编程(AOP)。AOP是...

    spring 常用的26个包

    本文将深入探讨Spring框架中常用的26个包,这些包是构建高效、可维护的Java应用的基础。 1. `org.springframework.beans`:这个包主要处理JavaBeans,包括属性的读取、设置、类型转换以及事件处理等。它还提供了...

    展示spring cloud的基本用法

    展示了spring cloud的基本用法。包括:1)一个基本的spring boot应用。2)分布式配置管理服务端。3)分布式配置管理客户端(微服务应用)。4)服务注册服务端。5)服务注册发现客户端(微服务应用)。6)实现spring ...

    Spring mvc中 RequestMapping 6个基本用法小结

    Spring MVC 中的 RequestMapping 6个基本用法小结 Spring MVC 是一个基于 Java 的 Web 应用程序框架,提供了强大的 RequestMapping 机制来处理 HTTP 请求。在 Spring MVC 中,RequestMapping 是一个核心组件,负责...

    spring3.1.1常用jar包

    在这个"spring3.1.1常用jar包"中,包含了一系列核心的Spring库,这些库是搭建基于Spring的应用程序所必需的。 1. **Spring Core**:这是Spring框架的基础,提供了依赖注入(DI)和面向切面编程(AOP)的核心功能。...

    spring2.5常用包

    这个压缩包包含的“spring常用包”很可能是为了帮助开发者理解并使用 Spring 2.5 的核心组件。让我们详细探讨一下 Spring 2.5 中的一些关键知识点: 1. **IoC(Inversion of Control)容器**:Spring 的核心特性是...

    spring mvc常用注解用法说明

    这是我根据自己使用springmvc的经验加上上网搜的资料整合而成,基本涵盖了springmvc常用的注解,以及注意的一些事项

    浅谈spring 常用注解

    浅谈Spring常用注解是Spring框架中的一些基本概念,了解这些概念对于 MASTERING SPRING Framework非常重要。本文将对Spring中常用的注解进行分类和介绍,并对每个注解的使用进行解释。 一、Bean定义注解 在Spring...

    spring boot常用注解.xlsx

    spring boot常用注解

    spring最基本jar

    这个“spring最基本jar”可能包含了Spring框架的基础组件,如Spring Core、Spring Beans、Spring AOP等,是学习和使用Spring框架的基础。理解并掌握这些知识点,能够帮助开发者有效地利用Spring框架构建高效、稳定的...

    Spring_AOP_学习小结 Spring_AOP_学习小结 Spring_AOP_学习小结

    本篇文章将详细阐述Spring AOP的基本概念、种类、代理原理、通知类型以及切入点,帮助你深入理解这一强大的编程模式。 一、AOP概念 1. Joinpoint(连接点):在Spring AOP中,Joinpoint指的是程序执行的某个特定点...

    spring常用模块介绍

    Spring框架是Java开发中最常用的轻量级框架之一,它的出现极大地简化了企业级应用的开发。本篇文章将针对Spring框架的常用模块进行详细介绍,旨在帮助初学者理解和掌握Spring的核心概念。 1. **IoC(控制反转)与DI...

    Spring常用包

    以上知识点只是Spring常用包的一部分,实际使用中还会涉及更多模块,如WebSocket、Task调度、缓存管理等。理解并熟练运用这些组件,可以有效地提升开发效率和应用质量。在实际项目中,可以根据需求选择相应的Spring...

    3.2Spring资源常用包

    "3.2Spring资源常用包"是一个集合了Spring 3.2版本中常用组件和库的压缩包,适用于构建基于Spring、Struts和Hibernate的集成解决方案。以下将详细解释这个包中可能包含的关键知识点。 1. **Spring核心模块**: - `...

    Spring常用的jar包.rar

    这个"Spring常用的jar包.rar"文件包含了一系列Spring框架的核心组件和依赖,使得开发者能够快速搭建一个基于Spring的项目环境。以下是对这些jar包及其重要性的详细解释: 1. **spring-core.jar**:这是Spring框架的...

    Spring系列之Spring常用注解总结1

    当在字段、构造函数、方法或参数上使用@Autowired时,Spring容器会在当前作用域中查找与目标类型匹配的bean,并自动注入。例如,我们可以修改动物园(Zoo)类如下: ```java package com.spring.model; import org...

Global site tag (gtag.js) - Google Analytics