SpringCloud学习(五)之RestTemplate几种请求方式的使用

    @Bean
    @LoadBalanced    //开启负载均衡
    RestTemplate restTemplateBean() {
        return new RestTemplate();
    }

    @Autowired
    @Qualifier("restTemplateBean")
    RestTemplate restTemplate;

1、GET

image.png

根据上图可以看出GET请求方式一共提供了两个函数 getForObject、getForEntity。每个函数都有三个重载方法。下面就分别来介绍一下:

getForEntity

该方法返回的是 ResponseEntity, 该对象是 Spring对 HTTP 请求响应的封装, 其中主要存储了 HTTP 的几个重要元素, 比如 HTTP 请求状态码的枚举对象 HttpStatus (也就是我们常说的 404、 500 这些错误码)、 在它的父类HttpEntity中还存储着HTTP 请求的头信息对象 HttpHeaders 以及泛型类型的请求体对象。

  • public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)
    url为请求的地址, responseType为请求响应体 body 的包装类型, urlVariables为url中的参数绑定。
ResponseEntity<String> entity = restTemplate.getForEntity("http://appUser/api/user/getName?name={1}", String.class, "哈哈哈哈");

其中第三个参数哈哈哈哈会替换 url 中的{1} 占位符。 这里需要注意的是, 由于urlVariables 参数是一个可变参数,最终会将它转换为一个Iterator, 所以它的顺序会对应 url 中 占位符定义的数字顺序

  • public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables)
    该方法提供的参数中, 只有 urlVariables 的参数类型与上面的方法不同。 这里使用了 Map 类型, 所以使用该方法进行参数绑定时,需要在占位符中指定Map 中参数的 key 值,比如 url定义为 http://appUser/api/user/getName?name={name),在Map 类型的 urlVariables 中, 我们就需要 put 一个 key为 userName 的参数来绑定url 中 {name} 占位符的值, 比如:
HashMap<String , String > map = new HashMap<>();
map.put("name","嘿哈嘿哈");
entity = restTemplate.getForEntity("http://appUser/api/user/getName?name={1}", String.class,map);
  • public <T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType)
    该方法使用URI 对象来替代之前的 url 和 urlVariables 参数来指定访问地址和参数绑定。 URI 是JDK java.net 包下的一个类,它表示一个统一资源标识符(Uniform Resource Identifier)引用。
//如果是中文记得转码
        String url = "http://appUser/api/user/getName?name=" + URLEncoder.encode("红红火火恍恍惚惚","UTF-8");
        URI uri = URI.create(url);
        entity =  restTemplate.getForEntity(uri,String.class);

getForObject

该方法可以理解为对 getForEntity 的进一步封装,
它通过 HttpMessageConverterExtractor 对 HTTP 的请求响应体 body内容进行对象转换, 实现请求直接返回包装好的对象内容

  • public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables)
  String rest = restTemplate.getForObject("http://appUser/api/user/getName?name={1}", String.class,name);
  • public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables)
        HashMap<String, Object> map = new HashMap<String,Object>();
        map.put("name",name);
        rest = restTemplate.getForObject("http://appUser/api/user/getName?name={name}", String.class,map);
  • public <T> T getForObject(URI url, Class<T> responseType)
        //如果是中文记得转码
        String url = "http://appUser/api/user/getName?name=" + URLEncoder.encode(name,"UTF-8");
        URI uri = URI.create(url);
        rest = restTemplate.getForObject(uri,String.class);

2、POST

服务提供者appUser增加两个接口

    @PostMapping("/addUser")
    public User addUser(User user){
        return user;
    }

    @PostMapping("/addUserJson")
    public User addUserJson(@RequestBody User user){
        return user;
    }

两个方法代表了不同的传参方式,一个是key/value格式,一个是json格式。


image.png

根据上图可以看出POST请求方式一共提供了两个函数 postForEntity、postForObject、postForLocation。每个函数都有三个重载方法。下面就分别来介绍一下:

postForEntity

  • public <T> ResponseEntity<T> postForEntity(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables)
  • public <T> ResponseEntity<T> postForEntity(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables)
  • public <T> ResponseEntity<T> postForEntity(URI url, @Nullable Object request, Class<T> responseType)

这些函数中的参数用法大部分与getForEntity一致。 这里需要注意的是新增加的
request参数, 该参数可以是一个普通对象, 也可以是一个HttpEntity对象。 如果是
一个普通对象, 而非HttpEntity对象的时候, RestTemplate会将请求对象转换为一
个HttpEntity对象来处理, 其中Object就是 request 的类型, request内容会被视
作完整的body来处理;而如果 request 是一个HttpEntity对象, 那么就会被当作一
个完成的HTTP请求对象来处理, 这个 request 中不仅包含了body的内容, 也包含了
header的内容。


image.png

示例:

//调用addUser方法
 MultiValueMap map = new LinkedMultiValueMap();
 map.add("id","1");
 map.add("name","gongj");
 ResponseEntity<User> userResponseEntity = restTemplate.postForEntity("http://appUser/api/user/addUser", map, User.class);

//调用addUserJson方法
User user = new User();
user.setId("87777");
user.setName("哈哈哈哈哈");
userResponseEntity = restTemplate.postForEntity("http://appUser/api/user/addUserJson", user, User.class);

注:需要使用 LinkedMultiValueMap ,不能使用HashMap。使用FormHttpMessageConverter进行解析。
可能有小伙伴可能会疑问了。RestTemplate中默认提供的转换器没有FormHttpMessageConverter啊?但是默认提供的AllEncompassingFormHttpMessageConverter继承了FormHttpMessageConverter。

image.png

image.png

传递类型为HashMap,可以发现被解析成了json字符串。用的是MappingJackson2HttpMessageConverter进行解析。


image.png

postForObject

  • public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables)
  • public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables)
  • public <T> T postForObject(URI url, @Nullable Object request, Class<T> responseType)
    该方法跟getForObject方法类似, 它的作用是简化postForEntity的后续处理。 通过直接将请求响应的body内容包装成对象来返回使用。requesta参数参考postForEntity的解释说明。

示例:

MultiValueMap map = new LinkedMultiValueMap();
map.add("id","1");
map.add("name","gongj");
User user = restTemplate.postForObject("http://appUser/api/user/addUser", map, User.class);

user.setId("99");
user.setName("高兴哈哈哈");
user = restTemplate.postForObject("http://appUser/api/user/addUserJson", user, User.class);

POST参数到底是key/value还是json,主要看第二个参数,如果第二个参数是MultiValueMap,则是以key/value形式传递。如果第二个参数是一个普通对象,则是以json形式传递。

postForLocation

  • public URI postForLocation(String url, @Nullable Object request, Object... uriVariables)
  • public URI postForLocation(String url, @Nullable Object request, Map<String, ?> uriVariables)
  • public URI postForLocation(URI url, @Nullable Object request)

由于 postForLocation 函数会返回新资源的URI, 该URI就相当于指定了返回类
型,所以此方法实现的POST请求不需要像postForEntity和postForObject那样指
定responseType。 其他的参数用法相同。

服务提供者appUser增加方法

@PostMapping("/register")
    public String register(User user){
        return "redirect:http://appUser/loginPage?name=" + user.getName();
    }

    @GetMapping("/loginPage")
    @ResponseBody
    public String loginPage(String name){
        return "loginPage:" + name;
    }

服务消费者appPay

  @GetMapping("/register")
    public void register(){
        MultiValueMap map = new LinkedMultiValueMap();
        map.add("id","1");
        map.add("name","gongj"); 
//调用register
        URI uri = restTemplate.postForLocation("http://appUser/register", map);
        System.out.println(uri);
//调用uri 
        String s = restTemplate.getForObject(uri, String.class);
        System.out.println(s);
    }

3、PUT请求

  • public void put(String url, @Nullable Object request, Object... uriVariables)
  • public void put(String url, @Nullable Object request, Map<String, ?> uriVariables)
  • public void put(URI url, @Nullable Object request)

PUT请求可以通过put方法调用,put方法的参数和前面介绍的postForObject方法的参数基本一致,只是put方法没有返回值而已。
示例:
服务提供者appUser增加接口

@PutMapping("/put/{id}")
    public User put(@PathVariable Integer id,@RequestBody User user){
        System.out.println(id + "=="+user);
        return user;
    }

服务消费者appPayr调用

 @RequestMapping("/put")
    public void put() {
        User user = new User();
        user.setId("99");
        user.setName("高兴哈哈哈");
        restTemplate.put("http://appUser/api/user/put/{1}", user,55);
    }

user 对象是我要提交的参数,最后的55用来替换前面的占位符{1}

4、DELETE请求

  • public void delete(String url, Object... uriVariables)
  • public void delete(String url, Map<String, ?> uriVariables)
  • public void delete(URI url)

delete请求可以通过delete方法调用来实现,如下例子:

服务提供者appUser增加接口

@DeleteMapping("/del/{id}")
    public void del(@PathVariable("id") String id){
        System.out.println(id);
    }

服务消费者appPayr调用

@RequestMapping("/delete")
public void delete() {
    restTemplate.delete("http://HELLO-SERVICE/getbook4/{1}", 100);
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,012评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,589评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,819评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,652评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,954评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,381评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,687评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,404评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,082评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,355评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,880评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,249评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,864评论 3 232
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,007评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,760评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,394评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,281评论 2 259

推荐阅读更多精彩内容