前言
Spring Boot 提供的restful服务这么方便,那有没有方便的调用方式呢?当然有了那就是RestTemplate
一、什么是RestTemplate
传统情况下在java代码里访问restful服务,一般使用Apache的HttpClient。不过此种方法使用起来太过繁琐。spring提供了一种简单便捷的模板类来进行操作,这就是RestTemplate。
二、启动服务
我们使用前一篇文章《架构实战篇(五):Spring Boot 表单验证和异常处理》做服务端提供服务
启动完毕后访问
http://localhost:8081/swagger/swagger-ui.html
测试服务是否启动正常
三、Java 客户端
让我们先来看下项目的目录结构
四、配置maven依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.itunion</groupId>
<artifactId>spring-boot-resttemplate</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.1.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<!-- 打war包用 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<packaging>war</packaging>
<properties>
<java.version>1.7</java.version>
</properties>
<build>
<!-- 打war包用 -->
<finalName>swagger</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- 打war包用,maven打包的时候告诉maven不需要web.xml,否刚会报找不到web.xml错误 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<!-- -->
</plugins>
</build>
</project>
五、编写程序入口
程序的入口基本都一样
package com.itunion;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.io.IOException;
@SpringBootApplication
public class Application {
public static void main(String[] args) throws IOException {
SpringApplication.run(Application.class, args);
}
}
六、RestTemplate 配置
在这里我们可以设置连接的超时时间 代理 等信息
package com.itunion.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class ApiConfig {
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
return new RestTemplate(factory);
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(5000);//单位为ms
factory.setConnectTimeout(5000);//单位为ms
return factory;
}
}
七、编写API 返回对象
API 请求肯定少不了返回对象,为了方便类型转换我们把User类复制了过来(实际开发中可以把api 公共的domain 等类带jar 包出来)
package com.itunion.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel("用户")
public class User {
@ApiModelProperty("编号")
private Long id;
@ApiModelProperty("用户名")
private String username;
@ApiModelProperty("姓")
private String firstName;
@ApiModelProperty("名")
private String lastName;
@ApiModelProperty("邮箱")
private String email;
@ApiModelProperty(hidden = true)// 密码不传输
@JsonIgnore
private String password;
@ApiModelProperty("状态")
private Integer userStatus;
// get set
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", email='" + email + '\'' +
", password='" + password + '\'' +
", userStatus=" + userStatus +
'}';
}
}
异常类
package com.itunion.model;
import java.o.Serializable;
public class ErrorBody implements Serializable {
private Integer code;
private String message;
private long timestamp = System.currentTimeMillis();
// get set
@Override
public String toString() {
return "ErrorBody{" +
"code=" + code +
", message='" + message + '\'' +
", timestamp=" + timestamp +
'}';
}
}
八、使用RestTemplate 远程调用
这里我们写了两个方法
- 当远程接口正常返回结果的时候我们会封装成User对象返回到前端
- 当远程调用返回 RestClientResponseException 异常的时候封装成ErrorBody对象(比如传入参数不合法等数据验证,不能返回逾期结果的时候会返回Error信息,这时候需要做处理)
package com.itunion.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.itunion.model.ErrorBody;
import com.itunion.model.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;
@Api(value = "用户", description = "用户")
@RequestMapping("/user")
@RestController
public class UserController {
@Autowired
private RestTemplate restTemplate;
@ApiOperation(value = "调用远程用户服务", notes = "调用远程用户服务")
@RequestMapping(value = "/info/{userId}", method = RequestMethod.GET)
public User info(@PathVariable("userId") String userId) throws IOException {
String apiURL = "http://localhost:8081/swagger/user/info/" + userId;
return restTemplate.getForObject(apiURL, User.class);
}
@ExceptionHandler(RestClientResponseException.class)
public ErrorBody exceptionHandler(HttpClientErrorException e) throws IOException {
return new ObjectMapper().readValue(e.getResponseBodyAsString(), ErrorBody.class);
}
}
九、修改端口
为了同时启动两个服务端口肯定是不能一样的了
server.port=8082
server.context-path=/
swagger.enable=true
十、启动程序和验证
服务端成功启动
客户端成功启动
访问客户端页面
http://localhost:8082/swagger-ui.html
测试正确的请求参数
测试错误的请求参数
好了 RestTemplate 的简单实用就到这里了
更多精彩内容
架构实战篇(一):Spring Boot 整合MyBatis
架构实战篇(二):Spring Boot 整合Swagger2
架构实战篇(三):Spring Boot 整合MyBatis(二)
架构实战篇(四):Spring Boot 整合 Thymeleaf
架构实战篇(五):Spring Boot 表单验证和异常处理
架构实战篇(六):Spring Boot RestTemplate的使用
关注我们
如果需要源码可以关注“IT实战联盟”公众号并留言(源码名称+邮箱),小萌看到后会联系作者发送到邮箱,也可以加入交流群和作者互撩哦~~~!