美文网首页工作专题java学习我爱编程
架构实战篇(六):Spring Boot RestTemplat

架构实战篇(六):Spring Boot RestTemplat

作者: IT实战联盟咖啡 | 来源:发表于2018-03-29 14:27 被阅读3169次
    Spring Boot RestTemplate.jpg

    前言

    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 远程调用

    这里我们写了两个方法

    1. 当远程接口正常返回结果的时候我们会封装成User对象返回到前端
    2. 当远程调用返回 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实战联盟”公众号并留言(源码名称+邮箱),小萌看到后会联系作者发送到邮箱,也可以加入交流群和作者互撩哦~~~!

    相关文章

      网友评论

      • IT人故事会:写得太好了。老铁,动动手指收藏了
        IT实战联盟咖啡:@我是小蚂蚁 这里主要讲的是使用 RestTemplate 来模拟 API 服务的调用,我想你可能需要 dubbo
        Antz_H碎碎念:楼主,不觉得这种方式很麻烦吗?还要定义地址,和传统的springmvc开发来说,还是不方便
        IT实战联盟咖啡:@IT人故事会 谢谢老铁支持

      本文标题:架构实战篇(六):Spring Boot RestTemplat

      本文链接:https://www.haomeiwen.com/subject/qrulcftx.html