SpringCloud初体验之REST服务与消费

前言

本萌新从今天开始进入对springcloud的学习阶段了,说实话之前刚学完Java的时候对编程信心十分的匮乏,学的Java基础稀里糊涂,说做网页吧连登陆注册增删改查都写不出来。试图从基础的spring开始学,但是那复杂的配置让我望而却步。于是从简化配置的springboot开始学习了,最开始学习的时候只是零散的学习,没有方向,只能做做简单的登陆啊注册啊(还十分的困难)。在bilibili上看了很多springboot系列的教程,可是自己的技术始终没有进步,原地徘徊三四个月终于决定突破这层阻碍,直接上项目。没错,就是在基础打得稀里糊涂的情况下,直接做项目。我把以前用Python的flask框架写的小程序用springboot重新写了一遍,还在之前的基础上加了几个功能,写完之后,觉得基本的crud能力完全打通,还通过这个项目学到了很多,包括小程序,这也对我学习vue奠定了一丢丢丢的基础。

后来进阶买了松哥(江南一点雨)的springboot+vue写的vhr项目,说实话我跟着他的视频一点点的敲一点点的吸收,现在做基本的前后端开发没什么问题,但是这个项目做完也同样发现了自己好多的知识盲点,所以学无止境嘛,一边扫盲一边拓展。总不能原地踏步是不是?

我也跟很多有点Java基础的兄弟聊过天,他们对自己web端学习的方法不明确,我自己一开始学的时候也走了很多弯路。现在想来我觉得学习编程首要的还是要打好自己的基础,每天的学习最好能写个博客记录下来,这样自己手机端也能查看,时时勤拂拭,莫使惹尘该嘛。学完之后一定要写个不大不小的项目,作为融会贯通。可能你会说,学的时候没问题,一上手项目就脑子一片空白啥也不会了。肯定的呀,写项目就是补你的空白的。写好项目,这样你再回头看,你就会对自己所学出有理解,这个时候想向上进阶,我建议去找网上高级的进阶资料或者买视频看,关于买什么样的视频,当然是那种中大型的前后端分离的项目,最好能带一些自己还没学但是想学的技术,比如我买的就是松哥的微人事项目视频,因为他用了vue来做前端,而vue又是现在最主流的前端开发框架,所以成了我的首选。这样一边学习一边总结,后面的就是看能不能在他的基础上对项目进行改造,不要求你会原创,能在人的基础上进行加功能改造功能,就足以说明自己能力又上升了一个档次。

好了,下面就看现在比较流行的springcloud框架,关于springcloud的介绍我这里就不做介绍了,很多博客都有,我这不赘述。直接看干货吧。

创建聚合工程

添加父工程依赖

<?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.study</groupId>
    <artifactId>springcloud</artifactId>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>SpringCloud-API</module>
        <module>SpringCloud-Provider</module>
        <module>SpringCloud-Consumer</module>
    </modules>
    <packaging>pom</packaging>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.1.4.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.47</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.1.10</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>1.3.2</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.16.16</version>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-core</artifactId>
                <version>1.2.3</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

创建API工程

我这里用了lombok插件,你们没有插件的就setget。
然后这里是给其他工程提供实体类的,所以需要实现序列化

package com.study.cloud.bean;

import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;

/**
 * @description:
 * 1.实体类必须实现序列化
 * @author: Leo
 * @createDate: 2020/2/8
 * @version: 1.0
 */
@Data
//@Accessors(chain = true)//开启链式写法
public class Book implements Serializable
{
    private Integer bookID;
    private String bookName;
    private Integer bookCounts;
    private String detail;
    private String db_source;

    public Book()
    {
    }

    public Book(String bookName, Integer bookCounts, String detail, String db_source)
    {
        this.bookName = bookName;
        this.bookCounts = bookCounts;
        this.detail = detail;
        this.db_source = db_source;
    }
}

创建服务者工程

添加依赖

<?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">
    <parent>
        <artifactId>springcloud</artifactId>
        <groupId>com.study</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>provider</artifactId>
    <dependencies>
        <dependency>
            <groupId>com.study</groupId>
            <artifactId>springcloud-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    </dependencies>

</project>

yml配置文件

server:
  port: 8001
mybatis:
  type-aliases-package: com.study.cloud.bean
  config-location: classpath:mybatis/mybatis-config.xml
  mapper-locations: classpath:mybatis/mapper/*.xml

#服务提供者
spring:
  application:
    name: springcloud-provider
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/leotemp?useUnicode=true&useSSL=false&characterEncodig=utf-8
    username: root
    password: 123456

mybatis配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.study.cloud.mapper.BookMapper">
    <insert id="addBook" parameterType="com.study.cloud.bean.Book">
        insert into books(bookName,bookCounts,detail,db_source)
        values (#{bookName},
        #{bookCounts},
        #{detail},
        #{db_source})
    </insert>
    <select id="queryById" parameterType="java.lang.Integer" resultType="com.study.cloud.bean.Book">
        select * from books where bookID=#{bookID};
    </select>
    <select id="queryAll" resultType="com.study.cloud.bean.Book">
        select * from books
    </select>
</mapper>

mapper层

package com.study.cloud.mapper;

import com.study.cloud.bean.Book;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * @description:
 * @author: Leo
 * @createDate: 2020/2/10
 * @version: 1.0
 */
@Mapper
@Repository
public interface BookMapper
{
    boolean addBook(Book book);
    Book queryById(Integer bookID);
    List<Book> queryAll();
}

service层

package com.study.cloud.service;

import com.study.cloud.bean.Book;

import java.util.List;

public interface BookService
{
    boolean addBook(Book book);

    Book queryById(Integer bookID);

    List<Book> queryAll();
}

实现类

package com.study.cloud.service;

import com.study.cloud.bean.Book;
import com.study.cloud.mapper.BookMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @description:
 * @author: Leo
 * @createDate: 2020/2/10
 * @version: 1.0
 */
@Service
public class BookServiceImp implements BookService
{
    @Autowired
    BookMapper bookMapper;

    public boolean addBook(Book book)
    {
        return bookMapper.addBook(book);
    }

    public Book queryById(Integer bookID)
    {
        return bookMapper.queryById(bookID);
    }

    public List<Book> queryAll()
    {
        return bookMapper.queryAll();
    }
}

控制层

package com.study.cloud.controller;

import com.study.cloud.bean.Book;
import com.study.cloud.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @description:
 * @author: Leo
 * @createDate: 2020/2/10
 * @version: 1.0
 */
@RestController
@RequestMapping("/book/provide")
public class BookController
{
    @Autowired
    BookService bookService;

    @PostMapping("/")
    public boolean addBook(@RequestBody Book book)
    {
        return bookService.addBook(book);
    }

    @GetMapping("/{bookID}")
    public Book queryById(@PathVariable("bookID") Integer bookID)
    {
        return bookService.queryById(bookID);
    }

    @GetMapping("/")
    public List<Book> queryAll()
    {
        return bookService.queryAll();
    }
}

最后定义启动类
上面就是最基本的数据的添加和查询。但是现在我们又要创建一个工程,这个工程是我们的消费者。

创建消费者模块

添加依赖

<?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">
    <parent>
        <artifactId>springcloud</artifactId>
        <groupId>com.study</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>consumer</artifactId>
<!--需要实体类和web-->
    <dependencies>
        <dependency>
            <groupId>com.study</groupId>
            <artifactId>springcloud-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>

二 修改端口,不要和之前那个工程一样 建议80
三、springcloud调用远程服务的话可以通过RestTemplate方法
第一步,要把RestTemplate注册到bean里

首先解释以下@configuration,它的主要作用就是在spring容器启动的时候,初始化IOC,使用了这个注解,那么该类就会在spring启动的时候,把@Bean注解标识的类进行依赖注入。@Bean理解的话,就好比在配置文件中配置.接下来就是在restTemplate的构造方法中添加httpRequest的工厂,使用连接池来优化http通信,默认使用长连接时间为30秒,再设置路由让http连接定向到指定的IP,然后设置并发数。再就是设置请求配置的超时时间,为了防止请求时间过长而引起资源的过渡浪费。如果在超过设置的timeout还没有数据返回,就直接断开连接。headers是添加默认的请求头,这里设置了传送的格式为json,语言为中-英等等属性。HttpClientBuilder.create设置请求头到HttpClient,然后在设置保持的时间,重试的次数,注入给httpClient进行封装。

package com.study.cloud.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * @description:
 * @author: Leo
 * @createDate: 2020/2/10
 * @version: 1.0
 */
@Configuration //这是springboot中的注解,他的作用相当于spring中的applicationContext.xml
public class ConfigBean
{
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

RestTemplate

说明:
现在restful接口越来越广泛,而如今很多接口摒弃了传统的配置复杂的webService开发模式,在java领域只需要很简单的springMvc就可以声明为一个控制器,再加上service层,就可以直接操作数据库成为一个灵活的接口。而我们请求接口的次数也会越来越多(最近我在和一个工具对接的时候,对方公司提供的接口全部由我们主动去调用),一般我们请求接口,都采用Apache Httpclient工具,这个工具稳定,既可以建立长连接,保持不错的性能,而它唯一的不足就是使用起来麻烦多变,并且要很多层判断处理,今天我要谈的就是spring对httpClient的再封装工具类,restTemplate,采用模板模式抽象出来的高效工具。有点类似于jdbcTemplate,今天我们就来一步步揭开它的使用方法

内置方法
在这里插入图片描述

客户端调用服务端

package com.study.cloud.controller;

import com.study.cloud.bean.Book;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * @description: 这里我是消费者,我在消费的时候需要自己有service层吗?我觉得显然是否定,那么问题来了,如果
 * controller没有service他该如何去调用service呢?
 * 通过RestTemplate
 * @author: Leo
 * @createDate: 2020/2/10
 * @version: 1.0
 */
@RestController
public class BookConSumController
{
    @Autowired
    RestTemplate restTemplate;//提供多种便捷访问远程http服务的方法,是一个简单的restful服务模板

    private static final String REST_URL_PREFIX="http://localhost:8001/book/provide";
    //public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables)
    // throws RestClientException
    @RequestMapping("/book/consumer/post")
    public boolean addBook(Book book){
        return restTemplate.postForObject(REST_URL_PREFIX+"/",book,Boolean.class);
    }
    @RequestMapping("/book/consumer/get/{bookID}")
    public Book getBookById(@PathVariable("bookID") Integer bookID){
        return restTemplate.getForObject(REST_URL_PREFIX+"/"+bookID,Book.class);
    }
    @RequestMapping("/book/consumer/get")
    public List<Book> getAllBook(){
        return restTemplate.getForObject(REST_URL_PREFIX+"/",List.class);
    }

}

这里调用的是**ForObject,他需要的参数是服务端的请求路径、参数、当前对象的类型

测试效果

服务端本地测试
http://localhost:8001/book/provide/
在这里插入图片描述
请求完全没毛病!
再看消费者端的调用
http://localhost/book/consumer/get
在这里插入图片描述
返回结果完全一致。

Author By 朝花不迟暮

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值