spring RestTemplate用法详解

<h1>
    <span class="link_title"><a href="/wwwihpccn/article/details/30496089">
    spring RestTemplate用法详解            
    </a></span>
</h1>
    <div class="article_manage clearfix">
    <div class="article_l">
        <span class="link_categories">
        标签:
          <a href="http://www.csdn.net/tag/spring" target="_blank" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">spring</a>
        </span>
    </div>
    <div class="article_r">
        <span class="link_postdate">2014-06-13 16:07</span>
        <span class="link_view" title="阅读次数">75404人阅读</span>
        <span class="link_comments" title="评论次数"> <a href="#comments" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_pinglun'])">评论</a>(3)</span>
        <span class="link_collect tracking-ad" data-mod="popu_171"> <a href="javascript:void(0);" onclick="javascript:collectArticle('spring+RestTemplate%e7%94%a8%e6%b3%95%e8%af%a6%e8%a7%a3','30496089');return false;" title="收藏">收藏</a></span>
         <span class="link_report"> <a href="#report" onclick="javascript:report(30496089,2);return false;" title="举报">举报</a></span>

    </div>
</div>
<div class="embody" style="display:none" id="embody">
    <span class="embody_t">本文章已收录于:</span>
    <div class="embody_c" id="lib" value="{&quot;err&quot;:0,&quot;msg&quot;:&quot;ok&quot;,&quot;data&quot;:[]}"></div>
</div>
<style type="text/css">        
        .embody{
            padding:10px 10px 10px;
            margin:0 -20px;
            border-bottom:solid 1px #ededed;                
        }
        .embody_b{
            margin:0 ;
            padding:10px 0;
        }
        .embody .embody_t,.embody .embody_c{
            display: inline-block;
            margin-right:10px;
        }
        .embody_t{
            font-size: 12px;
            color:#999;
        }
        .embody_c{
            font-size: 12px;
        }
        .embody_c img,.embody_c em{
            display: inline-block;
            vertical-align: middle;               
        }
         .embody_c img{               
            30px;
            height:30px;
        }
        .embody_c em{
            margin: 0 20px 0 10px;
            color:#333;
            font-style: normal;
        }
</style>
<script type="text/javascript">
    $(function () {
        try
        {
            var lib = eval("("+$("#lib").attr("value")+")");
            var html = "";
            if (lib.err == 0) {
                $.each(lib.data, function (i) {
                    var obj = lib.data[i];
                    //html += '<img src="' + obj.logo + '"/>' + obj.name + "&nbsp;&nbsp;";
                    html += ' <a href="' + obj.url + '" target="_blank">';
                    html += ' <img src="' + obj.logo + '">';
                    html += ' <em><b>' + obj.name + '</b></em>';
                    html += ' </a>';
                });
                if (html != "") {
                    setTimeout(function () {
                        $("#lib").html(html);                      
                        $("#embody").show();
                    }, 100);
                }
            }      
        } catch (err)
        { }
        
    });
</script>
  <div class="category clearfix">
    <div class="category_l">
       <img src="http://static.blog.csdn.net/images/category_icon.jpg">
        <span>分类:</span>
    </div>
    <div class="category_r">
                <label onclick="GetCategoryArticles('585323','wwwihpccn','top','30496089');">
                    <span onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_fenlei']);">学习讨论区<em>(33)</em></span>
                  <img class="arrow-down" src="http://static.blog.csdn.net/images/arrow_triangle _down.jpg" style="display:inline;">
                  <img class="arrow-up" src="http://static.blog.csdn.net/images/arrow_triangle_up.jpg" style="display:none;">
                    <div class="subItem">
                        <div class="subItem_t"><a href="http://blog.csdn.net/wwwihpccn/article/category/585323" target="_blank">作者同类文章</a><i class="J_close">X</i></div>
                        <ul class="subItem_l" id="top_585323">                            
                        </ul>
                    </div>
                </label>                    
    </div>
</div>
<script type="text/javascript" src="http://static.blog.csdn.net/scripts/category.js"></script>  

前面介绍过spring的MVC结合不同的view显示不同的数据,如:结合json的view显示json、结合xml的view显示xml文档。那么这些数据除了在WebBrowser中用JavaScript来调用以外,还可以用远程服务器的Java程序、C#程序来调用。也就是说现在的程序不仅在BS中能调用,在CS中同样也能调用,不过你需要借助RestTemplate这个类来完成。RestTemplate有点类似于一个WebService客户端请求的模版,可以调用http请求的WebService,并将结果转换成相应的对象类型。至少你可以这样理解!


Blog:http://blog.csdn.net/IBM_hoojo

http://hoojo.cnblogs.com/

一、准备工作

1、 下载jar包

spring各版本jar下载地址:http://ebr.springsource.com/repository/app/library/detail?name=org.springframework.spring

相关的依赖包也可以在这里找到:http://ebr.springsource.com/repository/app/library

2、 需要jar包如下

clip_image002

3、 当前工程的web.xml配置

xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" 
    xmlns="http://java.sun.com/xml/ns/j2ee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    
    
    <servlet>
        <servlet-name>dispatcherservlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
        <init-param>
            <param-name>contextConfigLocationparam-name>
            <param-value>/WEB-INF/dispatcher.xmlparam-value>
        init-param>
        <load-on-startup>1load-on-startup>
    servlet>
    
    <servlet-mapping>
        <servlet-name>dispatcherservlet-name>
        <url-pattern>*.dourl-pattern>
    servlet-mapping>
    
    <welcome-file-list>
      <welcome-file>index.jspwelcome-file>
    welcome-file-list>
web-app>

4、 WEB-INF中的dispatcher.xml配置

xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/util
    http://www.springframework.org/schema/util/spring-util-3.0.xsd">
 
    <context:component-scan base-package="com.hoo.*">
        
        <context:exclude-filter type="assignable" expression="com.hoo.client.RESTClient"/>
    context:component-scan>
 
    
    <bean id="handlerAdapter" class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
    
    
    <bean name="xStreamMarshallingView" class="org.springframework.web.servlet.view.xml.MarshallingView">
        <property name="marshaller">
            <bean class="org.springframework.oxm.xstream.XStreamMarshaller">  
                
                <property name="autodetectAnnotations" value="true"/>  
            bean>  
        property>
    bean>
        
    
    <bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
        <property name="order" value="3"/>
    bean>
 
    
    <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
        <property name="order" value="1" />
    bean>
    
beans>

5、 启动后,可以看到index.jsp 没有出现异常或错误。那么当前SpringMVC的配置就成功了。

二、REST控制器实现

REST控制器主要完成CRUD操作,也就是对于http中的post、get、put、delete。

还有其他的操作,如head、options、trace。

具体代码:

package com.hoo.controller;
 
import org.springframework.stereotype.Controller;
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.servlet.ModelAndView;
 
/**
 * function:SpringMVC REST示例
 * @author hoojo
 * @createDate 2011-6-9 上午11:34:08
 * @file RESTController.java
 * @package com.hoo.controller
 * @project SpringRestWS
 * @blog http://blog.csdn.net/IBM_hoojo
 * @email hoojo_@126.com
 * @version 1.0
 */
@RequestMapping("/restful")
@Controller
public class RESTController {
    
    @RequestMapping(value = "/show", method = RequestMethod.GET)
    public ModelAndView show() {
        System.out.println("show");
        ModelAndView model = new ModelAndView("xStreamMarshallingView");
        model.addObject("show method");
        return model; 
    }
    
    @RequestMapping(value = "/get/{id}", method = RequestMethod.GET)
    public ModelAndView getUserById(@PathVariable String id) {
        System.out.println("getUserById-" + id);
        ModelAndView model = new ModelAndView("xStreamMarshallingView");
        model.addObject("getUserById method -" + id);
        return model; 
    }
    
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public ModelAndView addUser(String user) {
        System.out.println("addUser-" + user);
        ModelAndView model = new ModelAndView("xStreamMarshallingView");
        model.addObject("addUser method -" + user);
        return model; 
    }
    
    @RequestMapping(value = "/edit", method = RequestMethod.PUT)
    public ModelAndView editUser(String user) {
        System.out.println("editUser-" + user);
        ModelAndView model = new ModelAndView("xStreamMarshallingView");
        model.addObject("editUser method -" + user);
        return model;
    }
    
    @RequestMapping(value = "/remove/{id}", method = RequestMethod.DELETE)
    public ModelAndView removeUser(@PathVariable String id) {
        System.out.println("removeUser-" + id);
        ModelAndView model = new ModelAndView("xStreamMarshallingView");
        model.addObject("removeUser method -" + id);
        return model;
    }
}

上面的方法对应的http操作:

/show -> get 查询
/get/id -> get 查询
/add -> post 添加
/edit -> put 修改
/remove/id -> delete 删除

在这个方法中,就可以看到RESTful风格的url资源标识

@RequestMapping(value = "/get/{id}", method = RequestMethod.GET)
public ModelAndView getUserById(@PathVariable String id) {
    System.out.println("getUserById-" + id);
    ModelAndView model = new ModelAndView("xStreamMarshallingView");
    model.addObject("getUserById method -" + id);
    return model; 
}

value=”/get/{id}”就是url中包含get,并且带有id参数的get请求,就会执行这个方法。这个url在请求的时候,会通过Annotation的@PathVariable来将url中的id值设置到getUserById的参数中去。 ModelAndView返回的视图是xStreamMarshallingView是一个xml视图,执行当前请求后,会显示一篇xml文档。文档的内容是添加到model中的值。

三、利用RestTemplate调用REST资源

代码如下:

package com.hoo.client;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
 
/**
 * function:RestTemplate调用REST资源
 * @author hoojo
 * @createDate 2011-6-9 上午11:56:16
 * @file RESTClient.java
 * @package com.hoo.client
 * @project SpringRestWS
 * @blog http://blog.csdn.net/IBM_hoojo
 * @email hoojo_@126.com
 * @version 1.0
 */
@Component
public class RESTClient {
    
    @Autowired
    private RestTemplate template;
    
    private final static String url = "http://localhost:8080/SpringRestWS/restful/";
    
    public String show() {
        return template.getForObject(url + "show.do", String.class, new String[]{});
    }
    
    public String getUserById(String id) {
        return template.getForObject(url + "get/{id}.do", String.class, id); 
    }
    
    public String addUser(String user) {
        return template.postForObject(url + "add.do?user={user}", null, String.class, user);
    }
    
    public String editUser(String user) {
        template.put(url + "edit.do?user={user}", null, user);
        return user;
    }
    
    public String removeUser(String id) {
        template.delete(url + "/remove/{id}.do", id);
        return id;
    }
}

RestTemplate的getForObject完成get请求、postForObject完成post请求、put对应的完成put请求、delete完成delete请求;还有execute可以执行任何请求的方法,需要你设置RequestMethod来指定当前请求类型。

RestTemplate.getForObject(String url, Class responseType, String... urlVariables)

参数url是http请求的地址,参数Class是请求响应返回后的数据的类型,最后一个参数是请求中需要设置的参数。

template.getForObject(url + "get/{id}.do", String.class, id);

如上面的参数是{id},返回的是一个string类型,设置的参数是id。最后执行该方法会返回一个String类型的结果。

下面建立一个测试类,完成对RESTClient的测试。代码如下:

package com.hoo.client;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests;
 
/**
 * function:RESTClient TEST
 * @author hoojo
 * @createDate 2011-6-9 下午03:50:21
 * @file RESTClientTest.java
 * @package com.hoo.client
 * @project SpringRestWS
 * @blog http://blog.csdn.net/IBM_hoojo
 * @email hoojo_@126.com
 * @version 1.0
 */
@ContextConfiguration("classpath:applicationContext-*.xml")
public class RESTClientTest extends AbstractJUnit38SpringContextTests {
    
    @Autowired
    private RESTClient client;
    
    public void testShow() {
        System.out.println(client.show());
    }
    
    public void testGetUserById() {
        System.out.println(client.getUserById("abc"));
    }
    
    public void testAddUser() {
        System.out.println(client.addUser("jack"));
    }
    
    public void testEditUser() {
        System.out.println(client.editUser("tom"));
    }
    
    public void testRemoveUser() {
        System.out.println(client.removeUser("aabb"));
    }
}

我们需要在src目录下添加applicationContext-beans.xml完成对restTemplate的配置。restTemplate需要配置MessageConvert将返回的xml文档进行转换,解析成JavaObject。

xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    
    <context:component-scan base-package="com.hoo.*"/>
    
    <bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
        <property name="messageConverters">
            <list>
                <bean class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
                    <property name="marshaller" ref="xStreamMarshaller"/>
                    <property name="unmarshaller" ref="xStreamMarshaller"/>
                bean>
            list>
        property>
    bean>
    
    <bean id="xStreamMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller">
        <property name="annotatedClasses">
            <array>                
            array>
        property>
    bean>
beans>

上面配置了xStreamMarshaller是和RESTController中的ModelAndView的view对应的。因为那边是用xStreamMarshaller进行编组的,所以RestTemplate这边也需要用它来解组。RestTemplate还指出其他的MarshallingHttpMessageConverter;

    <div id="digg" articleid="30496089">
        <dl id="btnDigg" class="digg digg_enable" onclick="btndigga();">
           
             <dt>顶</dt>
            <dd>1</dd>
        </dl>
       
          
        <dl id="btnBury" class="digg digg_enable" onclick="btnburya();">
          
              <dt>踩</dt>
            <dd>12</dd>               
        </dl>
        
    </div>
 <div class="tracking-ad" data-mod="popu_222"><a href="javascript:void(0);">&nbsp;</a>   </div>
<div class="tracking-ad" data-mod="popu_223"> <a href="javascript:void(0);">&nbsp;</a></div>
<script type="text/javascript">
            function btndigga() {
                $(".tracking-ad[data-mod='popu_222'] a").click();
            }
            function btnburya() {
                $(".tracking-ad[data-mod='popu_223'] a").click();
            }
        </script>
<div style="clear:both; height:10px;"></div>


    <div class="similar_article" style="">
            <h4>我的同类文章</h4>
            <div class="similar_c" style="margin:20px 0px 0px 0px">
                <div class="similar_c_t">
                            <label class="similar_cur">
                                <span style="cursor:pointer" onclick="GetCategoryArticles('585323','wwwihpccn','foot','30496089');">学习讨论区<em>(33)</em></span>
                            </label>
                </div>
               
                <div class="similar_wrap tracking-ad" data-mod="popu_141" style="max-height:195px;">
                    <a href="http://blog.csdn.net" style="display:none">http://blog.csdn.net</a>
                    <ul class="similar_list fl"><li><em>•</em><a href="http://blog.csdn.net/wwwihpccn/article/details/49185291" id="foot_aritcle_49185291undefined9180444562807679" target="_blank" title="Quarts 官方简单示例1">Quarts 官方简单示例1</a><span>2015-10-16</span><label><i>阅读</i><b>181</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/wwwihpccn/article/details/46683869" id="foot_aritcle_46683869undefined9050701796077192" target="_blank" title="文章标题">文章标题</a><span>2015-06-29</span><label><i>阅读</i><b>200</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/wwwihpccn/article/details/9473309" id="foot_aritcle_9473309undefined6578204312827438" target="_blank" title="spring mvc p:prefix=&quot;&quot;配置出错,导致访问路径出错">spring mvc p:prefix=""配置出错,导致访问路径出错</a><span>2013-07-25</span><label><i>阅读</i><b>3847</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/wwwihpccn/article/details/7431078" id="foot_aritcle_7431078undefined30097048985771835" target="_blank" title="汉语转拼音pinyin4j 代码实现">汉语转拼音pinyin4j 代码实现</a><span>2012-04-06</span><label><i>阅读</i><b>990</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/wwwihpccn/article/details/7049434" id="foot_aritcle_7049434undefined06726979208178818" target="_blank" title="同时运行两个TOMCAT的配置">同时运行两个TOMCAT的配置</a><span>2011-12-07</span><label><i>阅读</i><b>6901</b></label></li> </ul>

                    <ul class="similar_list fr"><li><em>•</em><a href="http://blog.csdn.net/wwwihpccn/article/details/46713839" id="foot_aritcle_46713839undefined08257538196630776" target="_blank" title="文件基本操作示例-文件读写">文件基本操作示例-文件读写</a><span>2015-07-01</span><label><i>阅读</i><b>159</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/wwwihpccn/article/details/44947981" id="foot_aritcle_44947981undefined25116078136488795" target="_blank" title="关于spring4和hibernate4整合,配置事务报“Cannot unwrap to requested type [javax.sql.DataSource]”错误的解决方法及心得">关于spring4和hibernate4整合,配置事务报“Cannot unwrap to requested type [javax.sql.DataSource]”错误的解决方法及心得</a><span>2015-04-08</span><label><i>阅读</i><b>3804</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/wwwihpccn/article/details/8149270" id="foot_aritcle_8149270undefined31842889450490475" target="_blank" title="tomcat集群及seeion共享">tomcat集群及seeion共享</a><span>2012-11-05</span><label><i>阅读</i><b>2742</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/wwwihpccn/article/details/7431047" id="foot_aritcle_7431047undefined47494069836102426" target="_blank" title="将汉字转换成汉语拼音方法,Pinyin4j入门教程">将汉字转换成汉语拼音方法,Pinyin4j入门教程</a><span>2012-04-06</span><label><i>阅读</i><b>1816</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/wwwihpccn/article/details/7048665" id="foot_aritcle_7048665undefined8418501266278327" target="_blank" title="Apache22 的Http代理出错 Proxy Error !">Apache22 的Http代理出错 Proxy Error !</a><span>2011-12-07</span><label><i>阅读</i><b>5502</b></label></li> </ul>
                <a href="http://blog.csdn.net/wwwihpccn/article/category/585323" class="MoreArticle">更多文章</a></div>
            </div>
        </div>    
<script type="text/javascript">
    $(function () {
        GetCategoryArticles('585323', 'wwwihpccn','foot','30496089');
    });
</script>
原文地址:https://www.cnblogs.com/jobs-lgy/p/6567887.html