1.股票数据采集环境准备

1.1背景说明

当前项目中的股票数据都是历史数据,不是实时最新的数据,而要想获取股票最新的数据,就需要定时调用第三方接口拉取最新数据流水;
​ Spring框架已为我们封装了一套访问远程http接口的模板工具:RestTemplate,借助于该工具,我们可访问第三方股票接口,获取股票最新数据。
​ RestTemplate本质上就是一个非常轻量级http客户端,使用简单且容易上手;

整体工程结构:
code

1.2构建股票数据采集工程

  1. 在stock_parent工程下构建stock_job子工程,并在pom中引入依赖:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    <?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>stock_parent</artifactId>
    <groupId>com.itheima.stock</groupId>
    <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>jar</packaging>
    <artifactId>stock_job</artifactId>
    <description>核心功能:拉去股票数据</description>
    <properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
    <dependency>
    <groupId>com.itheima.stock</groupId>
    <artifactId>stock_common</artifactId>
    <version>1.0-SNAPSHOT</version>
    </dependency>

    <!-- 基本依赖 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

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

    <build>
    <!--打包名称-->
    <finalName>${project.artifactId}</finalName>
    <plugins>
    <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
    </plugins>
    </build>
    </project>
  2. application.yml主配置文件与stock_backend工程一致:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    # 配置服务端口
    server:
    port: 8092
    spring:
    # 配置mysql数据源
    datasource:
    druid:
    username: root
    password: root
    url: jdbc:mysql://192.168.200.130:3306/stock_db?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.jdbc.Driver
    # 初始化时建立物理连接的个数。初始化发生在显示调用 init 方法,或者第一次 getConnection 时
    initialSize: 6
    # 最小连接池数量
    minIdle: 2
    # 最大连接池数量
    maxActive: 20
    # 获取连接时最大等待时间,单位毫秒。配置了 maxWait 之后,缺省启用公平锁,
    # 并发效率会有所下降,如果需要可以通过配置 useUnfairLock 属性为 true 使用非公平锁。
    maxWait: 60000
    # 配置mybatis
    mybatis:
    type-aliases-package: com.itheima.stock.pojo.* # 配置实体类扫描,取别名
    mapper-locations: classpath:mapper/*.xml # 配置扫描的xml的位置
    configuration:
    map-underscore-to-camel-case: true # 开启驼峰映射 table:user_name-->entity:userName

    # pagehelper配置
    pagehelper:
    helper-dialect: mysql #指定分页数据库类型(方言)
    reasonable: true #合理查询超过最大页,则查询最后一页
  1. 启动类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    package com.itheima.stock;
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    @SpringBootApplication
    @MapperScan("com.itheima.stock.mapper")
    public class JobApp {
    public static void main(String[] args) {
    SpringApplication.run(JobApp.class, args);
    }
    }
  2. 在stock_job工程下配置RestTemplate bean对象:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    package com.itheima.stock.config;

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

    /**
    * @author by itheima
    * @Date 2022/1/1
    * @Description 定义访问http服务的配置类
    */
    @Configuration
    public class HttpClientConfig {
    /**
    * 定义restTemplate bean
    * @return
    */
    @Bean
    public RestTemplate restTemplate(){
    return new RestTemplate();
    }
    }

2.RestTemplate快速入门

get请求携带参数访问外部url
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@SpringBootTest
public class TestRestTemplate {

@Autowired
private RestTemplate restTemplate;

/**
* 测试get请求携带url参数,访问外部接口
*/
@Test
public void test01(){
String url="http://localhost:6666/account/getByUserNameAndAddress?userName=itheima&address=shanghai";
/*
参数1:url请求地址
参数2:请求返回的数据类型
*/
ResponseEntity<String> result = restTemplate.getForEntity(url, String.class);
//获取响应头
HttpHeaders headers = result.getHeaders();
System.out.println(headers.toString());
//响应状态码
int statusCode = result.getStatusCodeValue();
System.out.println(statusCode);
//响应数据
String respData = result.getBody();
System.out.println(respData);
}
}

效果
code

get请求响应数据自动封装vo实体对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* 测试响应数据自动封装到vo对象
*/
@Test
public void test02(){
String url="http://localhost:6666/account/getByUserNameAndAddress?userName=itheima&address=shanghai";
/*
参数1:url请求地址
参数2:请求返回的数据类型
*/
Account account = restTemplate.getForObject(url, Account.class);
System.out.println(account);
}

@Data
public static class Account {
private Integer id;
private String userName;
private String address;

}

效果
code

请求头携带参数访问外部接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 请求头设置参数,访问指定接口
*/
@Test
public void test03(){
String url="http://localhost:6666/account/getHeader";
//设置请求头参数
HttpHeaders headers = new HttpHeaders();
headers.add("userName","zhangsan");
//请求头填充到请求对象下
HttpEntity<Map> entry = new HttpEntity<>(headers);
//发送请求
ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, entry, String.class);
String result = responseEntity.getBody();
System.out.println(result);
}

效果
code

POST请求模拟form表单访问外部接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
* post模拟form表单提交数据
*/
@Test
public void test04(){
String url="http://localhost:6666/account/addAccount";
//设置请求头,指定请求数据方式
HttpHeaders headers = new HttpHeaders();
//告知被调用方,请求方式是form表单提交,这样对方解析数据时,就会按照form表单的方式解析处理
headers.add("Content-type","application/x-www-form-urlencoded");
//组装模拟form表单提交数据,内部元素相当于form表单的input框
LinkedMultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
map.add("id","10");
map.add("userName","itheima");
map.add("address","shanghai");
HttpEntity<LinkedMultiValueMap<String, Object>> httpEntity = new HttpEntity<>(map, headers);
/*
参数1:请求url地址
参数2:请求方式 POST
参数3:请求体对象,携带了请求头和请求体相关的参数
参数4:响应数据类型
*/
ResponseEntity<Account> exchange = restTemplate.exchange(url, HttpMethod.POST, httpEntity, Account.class);
Account body = exchange.getBody();
System.out.println(body);
}

效果
code

POST请求发送JSON数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    /**
* post发送json数据
*/
@Test
public void test05(){
String url="http://localhost:6666/account/updateAccount";
//设置请求头的请求参数类型
HttpHeaders headers = new HttpHeaders();
//告知被调用方,发送的数据格式的json格式,对方要以json的方式解析处理
headers.add("Content-type","application/json; charset=utf-8");
//组装json格式数据
// HashMap<String, String> reqMap = new HashMap<>();
// reqMap.put("id","1");
// reqMap.put("userName","zhangsan");
// reqMap.put("address","上海");
// String jsonReqData = new Gson().toJson(reqMap);
String jsonReq="{\"address\":\"上海\",\"id\":\"1\",\"userName\":\"zhangsan\"}";
//构建请求对象
HttpEntity<String> httpEntity = new HttpEntity<>(jsonReq, headers);
/*
发送数据
参数1:请求url地址
参数2:请求方式
参数3:请求体对象,携带了请求头和请求体相关的参数
参数4:响应数据类型
*/
ResponseEntity<Account> responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, Account.class);
//或者
// Account account=restTemplate.postForObject(url,httpEntity,Account.class);
Account body = responseEntity.getBody();
System.out.println(body);
}

效果
code

获取接口响应的cookie数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* 获取请求cookie值
*/
@Test
public void test06(){
String url="http://localhost:6666/account/getCookie";
ResponseEntity<String> result = restTemplate.getForEntity(url, String.class);
//获取cookie
List<String> cookies = result.getHeaders().get("Set-Cookie");
//获取响应数据
String resStr = result.getBody();
System.out.println(resStr);
System.out.println(cookies);
}

效果
code