RestTemplate总结

RestTemplate:Spring 提供的一个同步的 Rest API 客户端。提供高度封装的接口,可以让我们非常方便地进行 Rest API 调用,大大提高客户端的编写效率。

Rest 类型方法名描述
DELETEdelete()执行HTTP DELETE操作
GETgetForObject()执行HTTP GET请求,将响应body封装成指定对象返回
getForEntity()执行HTTP GET请求,并将响应作为ResponseEntity返回。ResponseEntity包含了http响应状态码、响应头、响应体。
POSTpostForLocation()执行HTTP POST请求,并返回Location标头的返回值。
postForObject()执行HTTP POST请求,将响应body封装成指定对象返回
postForEntity()执行HTTP POST请求,并将响应作为ResponseEntity返回。ResponseEntity包含了http响应状态码、响应头、响应体。
PUTput()执行HTTP PUT请求,返回void
anyexchange()执行指定的HTTP方法,并将响应作为ResponseEntity返回。
execute()执行指定的HTTP方法,将响应body封装成指定对象返回

配置及使用

1.maven中引入jar包:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

 2.配置类:

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate() {
        // 创建http client工厂类,底层client使用JDK的 HttpURLConnection。
        // 默认没有连接池的概念,如有需要可换成Apache HttpClient或okhttp等其它http客户端
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        // 连接超时设置,毫秒,默认-1
        requestFactory.setConnectTimeout(30 * 1000);
        // 读取超时设置,毫秒,默认-1
        requestFactory.setReadTimeout(60 * 1000);
        RestTemplate restTemplate = new RestTemplate(requestFactory);
        // String类型的编解码设置
        restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        return restTemplate;
    }
}

3.使用:

@Service
public class RestTemplateTest {

    // tips:响应的数据,restTemplate默认无法识别的类型,会转化为LinkedHashMap
    @Resource
    private RestTemplate restTemplate;

    @PostConstruct
    public void init() {
        test1();
    }

    public void test1() {
        // GET
        Map<String, Object> mapGet = new HashMap<>();
        mapGet.put("pageNum", 1);   //替换url上的占位符 {pageNum}
        mapGet.put("pageSize", 10); //替换url上的占位符 {pageSize}

        String userRestString = restTemplate.getForObject("http://127.0.0.1:8080/users/{pageNum}/{pageSize}", String.class, mapGet);
        BaseResponse<List<User>> listBaseResponse = JSONObject.parseObject(userRestString, new TypeReference<BaseResponse<List<User>>>() {});

        String userString = restTemplate.getForObject("http://127.0.0.1:8080/users2?pageNum={pageNum}&pageSize={pageSize}", String.class, mapGet);
        BaseResponse<List<User>> listBaseResponse1 = JSONObject.parseObject(userString, new TypeReference<BaseResponse<List<User>>>() {});

        // POST
        Page page = new Page(); //请求body
        page.setPageNum(2);
        page.setPageSize(5);
        String userStringPost = restTemplate.postForObject("http://127.0.0.1:8080/usersByPost", page, String.class);
        BaseResponse<List<User>> listBaseResponsePost = JSONObject.parseObject(userStringPost, new TypeReference<BaseResponse<List<User>>>() {});

        // header
        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.setContentType(MediaType.APPLICATION_JSON);
        requestHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
        requestHeaders.set(HttpHeaders.COOKIE, "language=cn;");
        // body
        // Map<String, Object> body = new HashMap<>();
        // body.put("pageNum", 3);
        // body.put("pageSize", 4);
        // HttpEntity<Map<String, Object>> entity = new HttpEntity<>(body, requestHeaders);
        // or body
        Page pageBody = new Page();
        pageBody.setPageNum(3);
        pageBody.setPageSize(4);
        HttpEntity<Page> entity = new HttpEntity<>(pageBody, requestHeaders);
        // post
        String stringPostForObject = restTemplate.postForObject("http://127.0.0.1:8080/usersByPost", entity, String.class);
        BaseResponse<List<User>> listBaseResponse2 = JSONObject.parseObject(stringPostForObject, new TypeReference<BaseResponse<List<User>>>() {});

        // getForEntity()
        // ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://127.0.0.1:8080/users/{pageNum}/{pageSize}", String.class, mapGet);
        // String userRestString = responseEntity.getBody();

        // exchange()
        // ResponseEntity<String> exchange = restTemplate.exchange("http://127.0.0.1:8080/usersByPost", HttpMethod.POST, entity, String.class);
        // String exchangeBody = exchange.getBody();
        // ResponseEntity<String> getExchange = restTemplate.exchange("http://127.0.0.1:8080/users", HttpMethod.GET, entity, String.class);
    }

}

简单的工具类封装:

@Slf4j
public class HttpUtils {

    private static final RestTemplate restTemplate;

    static {
        // 创建http client工厂类,底层client使用JDK的 HttpURLConnection。
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        // 连接超时设置,毫秒,默认-1
        requestFactory.setConnectTimeout(30 * 1000);
        // 读取超时设置,毫秒,默认-1
        requestFactory.setReadTimeout(60 * 1000);
        restTemplate = new RestTemplate(requestFactory);
        // String类型的编解码设置
        restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(StandardCharsets.UTF_8));
    }

    /**
     * GET请求
     *
     * @param url URL
     *
     * @return 响应body
     *
     * @throws RestClientException
     */
    public static String get(String url) throws RestClientException {
        return restTemplate.getForObject(url, String.class);
    }

    /**
     * GET请求
     *
     * @param url          含占位符的URL,例:"http://127.0.0.1:8080/users?pageNum={pageNum}&pageSize={pageSize}"
     * @param uriVariables 替换占位符变量的值
     *
     * @return 响应body
     *
     * @throws RestClientException
     */
    public static String get(String url, Map<String, String> uriVariables) throws RestClientException {
        return restTemplate.getForObject(url, String.class, uriVariables);
    }

    public static String get(String url, HttpHeaders headers) throws RestClientException {
        return get(url, null, headers);
    }

    public static String get(String url, Map<String, String> uriVariables, HttpHeaders headers) throws RestClientException {
        HttpEntity<Object> httpEntity = new HttpEntity<>(null, headers);
        ResponseEntity<String> responseEntity;
        if (uriVariables == null) {
            responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, String.class);
        } else {
            responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, String.class, uriVariables);
        }
        return responseEntity.getBody();
    }

    public static String post(String url, Object requestBody) throws RestClientException {
        return post(url, requestBody, new HttpHeaders());
    }

    public static String post(String url, Object requestBody, HttpHeaders headers) throws RestClientException {
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
        HttpEntity<Object> entity = new HttpEntity<>(requestBody, headers);
        return restTemplate.postForObject(url, entity, String.class);
    }

}

提供http服务的代码:

@Slf4j
@RestController
@RequestMapping("/")
public class RestServerController {

    @GetMapping("/users/{pageNum}/{pageSize}")
    public BaseResponse<List<User>> httpRestGet(@PathVariable Integer pageNum, @PathVariable Integer pageSize) {
        log.info("pageNum={},pageSize={}", pageNum, pageSize);

        List<User> list = new ArrayList<>();
        User user1 = new User();
        user1.setName("张三");
        user1.setAge(20);
        list.add(user1);
        User user2 = new User();
        user2.setName("李四");
        user2.setAge(21);
        list.add(user2);

        return BaseResponse.success(list);
    }

    @GetMapping("/users2")
    public BaseResponse<List<User>> httpGet(@RequestParam Integer pageNum, @RequestParam Integer pageSize) {
        log.info("pageNum={},pageSize={}", pageNum, pageSize);

        List<User> list = new ArrayList<>();
        User user1 = new User();
        user1.setName("张三2");
        user1.setAge(22);
        list.add(user1);
        User user2 = new User();
        user2.setName("李四2");
        user2.setAge(32);
        list.add(user2);

        return BaseResponse.success(list);
    }

    @PostMapping("/usersByPost")
    public BaseResponse<List<User>> postTest(@RequestBody Page page, HttpServletRequest request) {
        log.info("page={}", page);
        log.info("request={}", request.getHeaderNames());

        List<User> list = new ArrayList<>();
        User user1 = new User();
        user1.setName("狗子");
        user1.setAge(30);
        list.add(user1);
        User user2 = new User();
        user2.setName("狗娃");
        user2.setAge(31);
        list.add(user2);

        return BaseResponse.success(list);
    }

}
@Data
public class User implements Serializable {
    private static final long serialVersionUID = -3581380362378545843L;

    private String name;
    private Integer age;

}

@Data
public class Page {

    private Integer pageNum;
    private Integer pageSize;

}

@Data
public class BaseResponse<T> implements Serializable {
    private static final long serialVersionUID = -619135033544136919L;
    private Integer code;
    private String msg;
    private T data;

    public static <T> BaseResponse<T> success(T data) {
        BaseResponse<T> response = new BaseResponse<T>();
        response.setCode(200);
        response.setMsg("success");
        response.setData(data);
        return response;
    }
}

4.RestTemplate + okhttp 

RestTemplate底层的http client使用okhttp工具类提供的 OkHttpClient,替代默认的JDK的HttpURLConnection。

1、引入jar

        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.9.2</version>
        </dependency>

2、配置类

@Configuration
public class RestTemplateConfig {

    /**
     * 基于OkHttp3配置RestTemplate
     */
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate(new OkHttp3ClientHttpRequestFactory());
    }

}

3、okhttp简介

OkHttp 是一个默认高效的 HTTP 客户端:

  • HTTP/2 支持允许对同一主机的所有请求共享一个套接字。
  • 连接池减少了请求延迟(如果 HTTP/2 不可用)。
  • 透明 GZIP 可缩小下载大小。
  • 响应缓存避免完全重复的网络请求。

OkHttp在网络出现问题时坚持:它会从常见的连接问题中默默恢复。如果您的服务有多个 IP 地址,则 OkHttp 将在第一次连接失败时尝试备用地址。这对于在冗余数据中心托管的 IPv4+IPv6 和服务是必需的。OkHttp 支持现代 TLS 功能(TLS 1.3、ALPN、证书锁定)。它可以配置为回退以实现广泛的连接。

使用 OkHttp 很容易。它的请求/响应 API 设计有流畅的构建器和不变性。它支持同步阻塞调用和带有回调的异步调用。

RestTemplate VS WebClient

通过 RestTemplate,我们可以非常方便的进行 Rest API 调用。但是在 Spring 5 中提供了支持异步调用的 WebClient。

RestTemplate 使用 Java Servlet API,因此是同步和阻塞的。相反,WebClient 是异步的,在等待响应返回时不会阻塞正在执行的线程。只有当程序就绪时,才会产生通知。
RestTemplate 仍将会被使用。但在某些情况下,与阻塞方法相比,非阻塞方法使用的系统资源要少得多。因此,在这些情况下,WebClient 不失为是更好的选择。

Spring Boot中的RestTemplate是一个用于发送HTTP请求的客户端工具。它可以与各种类型的RESTful服务进行交互,并支持多种HTTP方法(如GET、POST、PUT、DELETE等)。 使用RestTemplate,您可以发送HTTP请求并获取服务器返回的响应。它提供了一组方便的方法,用于处理请求和响应的各个方面,如请求头、请求体、路径参数、查询参数等。 下面是一个简单的示例,展示了如何使用RestTemplate发送GET请求: ```java RestTemplate restTemplate = new RestTemplate(); String url = "https://api.example.com/users/{id}"; String id = "123"; User user = restTemplate.getForObject(url, User.class, id); ``` 在上面的示例中,我们创建了一个RestTemplate实例,并指定了要发送请求的URL。我们还定义了一个路径参数`{id}`,并使用`restTemplate.getForObject()`方法发送GET请求。将服务器返回的JSON响应映射到一个User对象。 除了GET请求,RestTemplate还支持其他HTTP方法,如POST、PUT和DELETE。您可以使用不同的方法来发送不同类型的请求,并在需要时设置请求头、请求体等。 要使用RestTemplate,在Spring Boot项目中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> ``` 这将自动RestTemplate所需的所有依赖项,并使其可用于您的应用程序。 总结起来,RestTemplate是一个强大且易于使用的HTTP客户端工具,适用于与RESTful服务进行通信。它是Spring Boot中常用的组件之一,可以简化HTTP请求的处理过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值