欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

springboot集成RestTemplate及常见的用法说明

程序员文章站 2022-03-09 08:41:00
目录1、什么是resttemplate?2、resttemplate的优缺点二、配置resttemplate三、resttemplate常用方法1、getforentity2、getforobject...

一、背景介绍 

在微服务都是以http接口的形式暴露自身服务的,因此在调用远程服务时就必须使用http客户端。我们可以使用jdk原生的urlconnection、apache的http client、netty的异步http client, spring的resttemplate。

这里介绍的是resttemplate。resttemplate底层用还是httpclient,对其做了封装,使用起来更简单。

1、什么是resttemplate?

resttemplate是spring提供的用于访问rest服务的客户端,resttemplate提供了多种便捷访问远程http服务的方法,能够大大提高客户端的编写效率。

调用resttemplate的默认构造函数,resttemplate对象在底层通过使用java.net包下的实现创建http 请求,可以通过使用clienthttprequestfactory指定不同的http请求方式。

clienthttprequestfactory接口主要提供了两种实现方式

1、一种是simpleclienthttprequestfactory,使用j2se提供的方式(既java.net包提供的方式)创建底层的http请求连接。

2、一种方式是使用httpcomponentsclienthttprequestfactory方式,底层使用httpclient访问远程的http服务,使用httpclient可以配置连接池和证书等信息。

其实spring并没有真正的去实现底层的http请求(3次握手),而是集成了别的http请求,spring只是在原有的各种http请求进行了规范标准,让开发者更加简单易用,底层默认用的是jdk的http请求。

2、resttemplate的优缺点

  • 优点:连接池、超时时间设置、支持异步、请求和响应的编解码
  • 缺点:依赖别的spring版块、参数传递不灵活

resttemplate默认是使用simpleclienthttprequestfactory,内部是调用jdk的httpconnection,默认超时为-1

@autowired
resttemplate simpleresttemplate;
@autowired
resttemplate resttemplate;

二、配置resttemplate

1、引入依赖

<dependency>
    <groupid>org.apache.httpcomponents</groupid>
    <artifactid>httpclient</artifactid>
    <version>4.5.6</version>
</dependency>
<dependency>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-web</artifactid>
</dependency>

2、连接池配置

#最大连接数
http.maxtotal: 100
#并发数
http.defaultmaxperroute: 20
#创建连接的最长时间
http.connecttimeout: 1000
#从连接池中获取到连接的最长时间
http.connectionrequesttimeout: 500
#数据传输的最长时间
http.sockettimeout: 10000
#提交请求前测试连接是否可用
http.staleconnectioncheckenabled: true
#可用空闲连接过期时间,重用空闲连接时会先检查是否空闲时间超过这个时间,如果超过,释放socket重新建立
http.validateafterinactivity: 3000000

3、初始化连接池

package com.example.demo.config; 
import org.apache.http.client.httpclient;
import org.apache.http.client.config.requestconfig;
import org.apache.http.config.registry;
import org.apache.http.config.registrybuilder;
import org.apache.http.conn.socket.connectionsocketfactory;
import org.apache.http.conn.socket.plainconnectionsocketfactory;
import org.apache.http.conn.ssl.sslconnectionsocketfactory;
import org.apache.http.impl.client.httpclientbuilder;
import org.apache.http.impl.conn.poolinghttpclientconnectionmanager;
import org.springframework.beans.factory.annotation.value;
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import org.springframework.http.client.clienthttprequestfactory;
import org.springframework.http.client.httpcomponentsclienthttprequestfactory;
import org.springframework.web.client.resttemplate;
 
@configuration
public class resttemplateconfig {
    @value("${http.maxtotal}")
    private integer maxtotal;
 
    @value("${http.defaultmaxperroute}")
    private integer defaultmaxperroute;
 
    @value("${http.connecttimeout}")
    private integer connecttimeout;
 
    @value("${http.connectionrequesttimeout}")
    private integer connectionrequesttimeout;
 
    @value("${http.sockettimeout}")
    private integer sockettimeout;
 
    @value("${http.staleconnectioncheckenabled}")
    private boolean staleconnectioncheckenabled;
 
    @value("${http.validateafterinactivity}")
    private integer validateafterinactivity; 
 
    @bean
    public resttemplate resttemplate() {
        return new resttemplate(httprequestfactory());
    }
 
    @bean
    public clienthttprequestfactory httprequestfactory() {
        return new httpcomponentsclienthttprequestfactory(httpclient());
    }
 
    @bean
    public httpclient httpclient() {
        registry<connectionsocketfactory> registry = registrybuilder.<connectionsocketfactory>create()
                .register("http", plainconnectionsocketfactory.getsocketfactory())
                .register("https", sslconnectionsocketfactory.getsocketfactory())
                .build();
        poolinghttpclientconnectionmanager connectionmanager = new poolinghttpclientconnectionmanager(registry);
        connectionmanager.setmaxtotal(maxtotal); // 最大连接数
        connectionmanager.setdefaultmaxperroute(defaultmaxperroute);    //单个路由最大连接数
        connectionmanager.setvalidateafterinactivity(validateafterinactivity); // 最大空间时间
        requestconfig requestconfig = requestconfig.custom()
                .setsockettimeout(sockettimeout)        //服务器返回数据(response)的时间,超过抛出read timeout
                .setconnecttimeout(connecttimeout)      //连接上服务器(握手成功)的时间,超出抛出connect timeout
                .setstaleconnectioncheckenabled(staleconnectioncheckenabled) // 提交前检测是否可用
                .setconnectionrequesttimeout(connectionrequesttimeout)//从连接池中获取连接的超时时间,超时间未拿到可用连接,会抛出org.apache.http.conn.connectionpooltimeoutexception: timeout waiting for connection from pool
                .build();
        return httpclientbuilder.create()
                .setdefaultrequestconfig(requestconfig)
                .setconnectionmanager(connectionmanager)
                .build();
    } 
}

4、使用示例

resttemplate是对httpcilent的封装,所以,依httpcilent然可以继续使用httpcilent。看下两者的区别

httpcilent:

@requestmapping("/testhttpclient")
@responsebody
public object getuser(string msg) throws ioexception {
    closeablehttpclient closeablehttpclient = httpclients.createdefault();
    httpget get = new httpget("http://192.168.1.100:8080/user/getalluser");
    closeablehttpresponse response = closeablehttpclient.execute(get);
    return entityutils.tostring(response.getentity(), "utf-8");
}

resttemplate:

@requestmapping("/testresttemplate")
@responsebody
public object testresttemplate() throws ioexception {
    responseentity result = resttemplate.getforentity("http://192.168.1.100:8080/user/getalluser",responseentity.class;
    return result.getbody();
}

resttemplate更简洁了。

三、resttemplate常用方法

1、getforentity

getforentity方法的返回值是一个responseentity<t>,responseentity<t>是spring对http请求响应的封装,包括了几个重要的元素,如响应码、contenttype、contentlength、响应消息体等。比如下面一个例子:

@requestmapping("/sayhello")
public string sayhello() {
    responseentity<string> responseentity = resttemplate.getforentity("http://hello-service/sayhello?name={1}", string.class, "张三");
    return responseentity.getbody();
}
@requestmapping("/sayhello2")
public string sayhello2() {
    map<string, string> map = new hashmap<>();
    map.put("name", "李四");
    responseentity<string> responseentity = resttemplate.getforentity("http://hello-service/sayhello?name={name}", string.class, map);
    return responseentity.getbody();
}

2、getforobject

getforobject函数实际上是对getforentity函数的进一步封装,如果你只关注返回的消息体的内容,对其他信息都不关注,此时

可以使用getforobject,举一个简单的例子,如下:

@requestmapping("/book2")
public book book2() {
    book book = resttemplate.getforobject("http://hello-service/getbook1", book.class);
    return book;
}

3、postforentity

@requestmapping("/book3")
public book book3() {
    book book = new book();
    book.setname("红楼梦");
    responseentity<book> responseentity = resttemplate.postforentity("http://hello-service/getbook2", book, book.class);
    return responseentity.getbody();
}
  • 方法的第一参数表示要调用的服务的地址
  • 方法的第二个参数表示上传的参数
  • 方法的第三个参数表示返回的消息体的数据类型

4、postforobject

如果你只关注,返回的消息体,可以直接使用postforobject。用法和getforobject一致。

5、postforlocation

postforlocation也是提交新资源,提交成功之后,返回新资源的uri,postforlocation的参数和前面两种的参数基本一致,只不过该方法的返回值为uri,这个只需要服务提供者返回一个uri即可,该uri表示新资源的位置。

6、put请求

在resttemplate中,put请求可以通过put方法调用,put方法的参数和前面介绍的postforentity方法的参数基本一致,只是put方法没有返回值而已。举一个简单的例子,如下:

@requestmapping("/put")
public void put() {
    book book = new book();
    book.setname("红楼梦");
    resttemplate.put("http://hello-service/getbook3/{1}", book, 99);
}

7、delete请求

delete请求我们可以通过delete方法调用来实现,如下例子:
@requestmapping("/delete")
public void delete() {
    resttemplate.delete("http://hello-service/getbook4/{1}", 100);
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。