作者 朱兆平

init

/logs/
/target/
/out/
.idea/
messagebus-trans-message.iml
src/test/
target/
... ...
#上传文件的路径,要带斜杠
web:
upload-path: upload/
server:
port: 11112
servlet:
context-path: ${SERVER_CONTEXTPATH:}
spring:
devtools:
add-properties: false
profiles:
active: dev
mvc:
#静态资源,设置上传文件的访问,
static-path-pattern: /**
resources:
static-locations: classpath:/META-INF/resources/,classpath:/static,classpath:/resources/,file:${web.upload-path}
application:
name: message-bus-trans-message
redis:
# host: 127.0.0.1
host: 8.131.245.248
port: 6379
password: dsly@admin
jackson:
serialization:
FAIL_ON_EMPTY_BEANS: false
#springboot2.0之后会把Date类型字段自动给转成UTC字符串 如:1990-11-26T16:00:00.000+0000,如果想转成时间戳在application.properties配置文件增加以下配置
date-format: yyyy-MM-dd HH:mm:ss
#时区必须要设置
time-zone: GMT+8
#ALWAYS的意思是即时属性为null,仍然也会输出这个key
default-property-inclusion: always
cloud:
#eureka主机名,会在控制页面中显示
#DEV环境关闭注册。
features:
enabled: true
discovery:
enabled: true
service-registry:
auto-registration:
enabled: true
datasource:
type: com.alibaba.druid.pool.DruidDataSource
#oracle
#driver-class-name=oracle.jdbc.OracleDriver
#url=jdbc:oracle:thin:@10.50.3.68:1521:CGODW
#username=CGOETL
#password=1q2w3e4r
#spring datasource mysql,注意编码配置,缺少数据库编码配置容易引起中文入库乱码
# url: jdbc:mysql://118.31.66.166:3306/station?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
url: jdbc:mysql://8.131.245.248:3306/zz_logistics?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
username: root
password: ZZdsly123
driver-class-name: com.mysql.cj.jdbc.Driver
#配置初始化大小/最小/最大
druid:
initial-size: 10
min-idle: 10
max-active: 20
#获取连接等待超时时间
max-wait: 60000
#一个连接在池中最小生存的时间
min-evictable-idle-time-millis: 300000
#间隔多久进行一次检测,检测需要关闭的空闲连接
time-between-eviction-runs-millis: 60000
#mysql
validation-query: SELECT 1 FROM DUAL
#oracle
#druid.validation-query:SELECT 'x' FROM DUAL
test-while-idle: true
test-on-borrow: false
test-on-return: false
default-auto-commit: true
# tomcat:
# max-wait: 10
# max-idle: 10000
# min-idle: 5
# initial-size: 5
eureka:
instance:
#eureka服务器页面中status的请求路径
# status-page-url: http://${eureka.instance.hostname}:${server.port}/index
prefer-ip-address: true
instance-id: ${spring.cloud.client.ip-address}:${server.port}
hostname: ${spring.cloud.client.ip-address}
lease-renewal-interval-in-seconds: 15
lease-expiration-duration-in-seconds: 45
health-check-url-path: /actuator/health
metadata-map:
user:
name: "admin" #These two are needed so that the server
password: "123456"
client:
#eureka注册中心服务器地址
service-url:
# defaultZone: http://127.0.0.1:12345/eureka/
defaultZone: http://192.168.1.53:12345/eureka/
registry-fetch-interval-seconds: 30
management:
endpoints:
enabled-by-default: true
web:
exposure:
include: "*"
endpoint:
health:
show-details: always
shutdown:
enabled: true
mybatis:
mapper-locations: classpath:mapping/*.xml
type-aliases-package: com.sunyo.usercenter.heartbeat.model
pagehelper:
#auto-dialect: true
#auto-runtime-dialect: true
helper-dialect: mysql
reasonable: true
support-methods-arguments: true
params: count=countSql
#debug配置,debug或者为true的时候,logback才会记录和写入日志文件
trace: false
debug: true
logging:
file:
path: ./logs/
name: system.log
config: config/logback-dev.xml
#转移到logback配置文件中
#level:
#org.apache.tomcat: info
#com.tianbo.warehouse.dao: DEBUG
#org.springframework.security: trace
#日志配置,输出到文本,
#Java Web Token 时效时间,单位秒
jwt:
max-alive: 30000
message-bus:
url:
#账户登录地址
login-url: http://36.134.143.171:8083/api/zz-uaa/common/bus/login
#心跳地址
hearbit-url: http://36.134.143.171:8083/api/cloud-user-center-heartbeat/heartbeat
#报文发送地址
send-url: http://36.134.143.171:8083/api/kafka-server-producer/kafka/send
#报文接收地址
get-url: http://36.134.143.171:8083/api/kafka-server-consumer/kafka/receive
auth:
username: yangyucheng
password: 111111
#心跳间隔时间默认10秒,单位毫秒
heartbit-interval: 10000
info:
version: 1.0
description: "消息总线-消息转发服务。[转发大数据小组消息到总线上]"
... ...
<?xml version="1.0" encoding="UTF-8"?>
<!--参考文档链接:https://blog.csdn.net/qq_34912478/article/details/80877132-->
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true -->
<!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<configuration scan="true" scanPeriod="60 seconds">
<!--<include resource="org/springframework/boot/logging/logback/base.xml" />-->
<contextName>logback</contextName>
<!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 -->
<property name="log.path" value="./logs" />
<!-- 彩色日志 -->
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!--输出到控制台-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!--输出到文件-->
<!-- 时间滚动输出 level为 DEBUG 日志 -->
<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/log_debug.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志归档 -->
<fileNamePattern>${log.path}/debug/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录debug级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>debug</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 INFO 日志 -->
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/log_info.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天日志归档路径以及格式 -->
<fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录info级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 WARN 日志 -->
<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/log_warn.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录warn级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>warn</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 ERROR 日志 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/log_error.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录ERROR级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!--
<logger>用来设置某一个包或者具体的某一个类的日志打印级别、
以及指定<appender>。<logger>仅有一个name属性,
一个可选的level和一个可选的addtivity属性。
name:用来指定受此logger约束的某一个包或者具体的某一个类。
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。
如果未设置此属性,那么当前logger将会继承上级的级别。
addtivity:是否向上级logger传递打印信息。默认是true。
-->
<!--<logger name="org.springframework.web" level="info"/>-->
<!--<logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/>-->
<!--
使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作:
第一种把<root level="info">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息
第二种就是单独给dao下目录配置debug模式,代码如下,这样配置sql语句会打印,其他还是正常info级别:
-->
<!--
root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
不能设置为INHERITED或者同义词NULL。默认是DEBUG
可以包含零个或多个元素,标识这个appender将会添加到这个logger。
-->
<logger name="com.sunyo.usercenter.heartbeat.dao" level="debug" />
<!--开发环境:打印控制台-->
<springProfile name="dev">
<logger name="org.apache.tomcat" level="info" />
<logger name="com.sunyo.usercenter.heartbeat" level="debug" />
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="DEBUG_FILE" />
<appender-ref ref="INFO_FILE" />
<appender-ref ref="WARN_FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
</springProfile>
<!--生产环境:输出到文件-->
<springProfile name="pro">
<root level="info">
<appender-ref ref="CONSOLE" />
<appender-ref ref="DEBUG_FILE" />
<appender-ref ref="INFO_FILE" />
<appender-ref ref="ERROR_FILE" />
<appender-ref ref="WARN_FILE" />
</root>
</springProfile>
</configuration>
\ No newline at end of file
... ...
<?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>
<packaging>jar</packaging>
<groupId>com.tianbo</groupId>
<artifactId>messagebus-trans-message</artifactId>
<version>1.0-SNAPSHOT</version>
<description>消息转发服务</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.11.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
<swagger2_version>2.9.2</swagger2_version>
<fastjson_version>1.2.73</fastjson_version>
<lombok_sersion>1.18.6</lombok_sersion>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok_sersion}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson_version}</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
... ...
package com.tianbo.messagebus;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableEurekaClient
@EnableScheduling
public class MessageTransApplication {
public static void main(String[] args) {
SpringApplication.run(MessageTransApplication.class, args);
}
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(10);
return taskScheduler;
}
}
... ...
package com.tianbo.messagebus.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tianbo.messagebus.service.MessageBusProcessor;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.util.Date;
@RestController()
@RequestMapping("/")
public class HeartbeatController implements Serializable {
private static final long serialVersionUID = 1L;
@Autowired
private HttpServletRequest request;
@Autowired
MessageBusProcessor messageBusDemo;
@PostMapping("login")
public void login(){
messageBusDemo.login();
}
@PostMapping("getmsg")
public void getmsg(){
messageBusDemo.getMsg();
}
}
... ...
package com.tianbo.messagebus.controller.response;
import java.io.Serializable;
public class ResultJson<T> implements Serializable{
private static final long serialVersionUID = 1L;
// 状态码 正确为200
private String code = "200";
// 描述
private String msg = "";
private String error;
// 返回对象
private T data;
//返回的JWT
private String jwtToken;
public ResultJson() {
}
public ResultJson(String code) {
this.code = code;
}
public ResultJson(String code, String msg) {
this.code = code;
this.msg = msg;
}
public ResultJson(T data) {
this.data = data;
}
public ResultJson(String code, String msg, T data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public ResultJson(String code, String msg, T data,String jwtToken) {
this.code = code;
this.msg = msg;
this.data = data;
this.jwtToken = jwtToken;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public String getJwtToken() {
return jwtToken;
}
public void setJwtToken(String jwtToken) {
this.jwtToken = jwtToken;
}
}
... ...
package com.tianbo.messagebus.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.io.Serializable;
@Service
@EnableAsync
@Slf4j
public class MessageBusProcessor {
/**http://10.161.4.20:8083/
* 账户登录地址
*/
@Value("${message-bus.url.login-url}")
private String LOGIN_URL;
/**
* 账号名
*/
@Value("${message-bus.auth.username}")
private String USER_NAME;
// private static final String USER_NAME = "HYYW";
/**
* 登陆密码
*/
@Value("${message-bus.auth.password}")
private String USER_PASS;
// private static final String USER_PASS = "ZZecargo123";
/**
* 心跳接口地址
*/
@Value("${message-bus.url.hearbit-url}")
private String HEARTBEAT_URL;
/**
* 心跳间隔时间 单位S
*/
@Value("${message-bus.heartbit-interval}")
private int HEARTBIT_INTERVAL;
/**
* 发送报文地址
*/
@Value("${message-bus.url.send-url}")
private String SEND_MSG_URL;
/**
* 接收报文地址
*/
@Value("${message-bus.url.get-url}")
private String GET_MSG_URL;
/**
* 存储登录后的token
*/
private static String TOKEN = "";
/**
* 登录成功状态
*/
private static Boolean LOGIN_STATUS=false;
/**
* HTTP请求框架
*/
@Resource
private RestTemplate restTemplate;
/**
* 发起登录,存储token
*
* @return
*/
public Boolean login() {
try {
/*
* 发起HTTP 登录请求
* 登录接口的请求头为application/x-www-form-urlencoded
*/
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
/*
* 请求参数
*/
MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
params.add("username", USER_NAME);
params.add("password", USER_PASS);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(params, headers);
/*
* 提交HTTP访问,获取返回信息
*/
ResponseEntity<String> response = restTemplate.postForEntity(LOGIN_URL, request, String.class);
// 输出结果
log.info(response.getBody());
/*
校验是否登录成功
*/
if (response.getStatusCode().equals(HttpStatus.OK)) {
/**
* 从返回信息中确定是否登录成功,并取得token
* 返回格式
* {
"code":200,
"data":{
"account":"yangyucheng",
"token":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI2MCIsIm5hbWUiOiLmnajnjonmiJDmtYvor5UiLCJpZCI6NjAsImlhdCI6MTYxNzM0ODM3MiwiYWNjb3VudCI6Inlhbmd5dWNoZW5nIn0.ElAs7BtV1tu6ApQXuPXzgXUgvja76bjEb-zxqhUON48"
},
"message":"success",
"success":true,
"time":20210402152612604
}
*/
JSONObject resJson = JSON.parseObject(response.getBody());
JSONObject resData = resJson.getJSONObject("data");
String resCode = resJson.getString("code");
/*
校验并获取登陆成功后返回的token
*/
String authToken = resData.getString("token");
if ("200".equals(resCode) && !StringUtils.isEmpty(authToken) && authToken.length() > 10) {
LOGIN_STATUS = true;
//设置请求头部Authorization为token, token的类型为Bearer
TOKEN = authToken;
/*
登录成功开始心跳
*/
// startHeartBit();
log.info("登录成功");
return true;
}else {
log.error("登录失败");
return false;
}
} else {
log.error("登录失败");
return false;
}
} catch (Exception e) {
log.error("登录失败->{}",e.toString());
return false;
}
}
/**
* 定时心跳,维持在线状态,每10秒访问一次心跳接口
*/
public void startHeartBit() {
try {
while (true) {
heartBit();
Thread.sleep(HEARTBIT_INTERVAL);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Scheduled(fixedRate = 10000)
public void heartBit() {
if (!StringUtils.isEmpty(TOKEN) && LOGIN_STATUS){
/*
* 发起HTTP 登录请求
* 登录接口的请求头为application/x-www-form-urlencoded
*/
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
/*
* 设置获取到的token到头部信息Authorization节点中
*/
headers.setBearerAuth(TOKEN);
/*
* 心跳接口无参数,访问接口即可
*/
MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(params, headers);
/*
* 提交HTTP访问,获取返回信息
*/
ResponseEntity<String> response = restTemplate.postForEntity(HEARTBEAT_URL, request, String.class);
// 输出结果
System.out.println(response.getBody());
if (response.getStatusCode().equals(HttpStatus.OK)) {
log.info("心跳成功");
} else {
log.error("心跳失败");
}
}
}
/**
* 发送消息
*
* @return
*/
public Boolean sendMsg(MSG msg) {
if (LOGIN_STATUS) {
/*
* 发起HTTP 登录请求
* 登录接口的请求头为application/json
*/
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
MSGS msgs = new MSGS();
msg.getHEADER().setSNDR("HYYW");
msgs.setMSG(msg);
/*
设置要发送的实体类并将实体转换成Json字符串,这里以MAP类型举例
*/
// Map<String, String> dataModel = new HashMap<>();
// dataModel.put("flightNo", "CV987");
// dataModel.put("flightDate", "MAY01");
// dataModel.put("waybillNo", "172-12345678");
// dataModel.put("weight", "20.01");
// dataModel.put("piece", "2");
// msg.getMSG().setBODY(JSON.toJSONString(dataModel));
/*
* 设置获取到的token到头部信息Authorization节点中
*/
headers.setBearerAuth(TOKEN);
/*
* 发起消息接口访问,发送消息
*/
HttpEntity<MSGS> request = new HttpEntity<MSGS>(msgs, headers);
ResponseEntity<String> response = restTemplate.postForEntity(SEND_MSG_URL, request, String.class);
JSONObject resJson = JSON.parseObject(response.getBody());
String code = resJson.getString("code");
System.out.println(response.getBody());
if (response.getStatusCode().equals(HttpStatus.OK) && "200".equals(code)) {
log.info("消息发送成功");
return true;
} else {
log.error("消息发送失败");
return false;
}
}
return false;
}
/**
* 收取消息
*
* @return
*/
@Async
@Scheduled(fixedRate = 300)
public JSONArray getMsg() {
if(!LOGIN_STATUS){
login();
return null;
}
/*
* 发起HTTP 登录请求
* 登录接口的请求头为application/json
*/
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.setBearerAuth(TOKEN);
/*
* 请求参数拼装
*/
MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
params.add("username", "HYYW");
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(params, headers);
/*
* 提交HTTP访问,获取返回信息
*/
ResponseEntity<String> response = restTemplate.postForEntity(GET_MSG_URL, request, String.class);
// 输出结果
log.info("获取到消息返回---{}---",response.getBody());
/*
* 从返回信息中确定是否获取到消息
*/
JSONObject resJson = JSON.parseObject(response.getBody());
String code = resJson.getString("code");
if (response.getStatusCode().equals(HttpStatus.OK) && "200".equals(code)) {
JSONArray data = resJson.getJSONArray("data");
log.info("消息接收成功,接收消息为>>>{}<<<",data.toString());
for (int i = 0; i<data.size() ; i++) {
/*
取得是大数据小组的实体,他们的msg.body的封装是以对象实体object封装的。不是json字符串。
*/
String msg = data.getObject(i,String.class);
JSONObject rootJson = JSON.parseObject(msg);
JSONObject msgJson = rootJson.getJSONObject("MSG");
JSONObject body = msgJson.getJSONObject("BODY");
HEADER msgHeader = msgJson.getObject("HEADER",HEADER.class);
MSG transMsg= new MSG();
String transBody = body.toJSONString();
transMsg.setHEADER(msgHeader);
transMsg.setBODY(transBody);
transMsg.toString();
/*
自定义对返回数据的处理
*/
log.info("开始转发消息");
Boolean sendResult = sendMsg(transMsg);
/**
* todo:消息失败处理
*/
if(!sendResult){
//todo:消息备份或者重发?
}
}
return data;
} else {
log.error("消息获取失败");
return new JSONArray();
}
}
/**
* 读取备份消息并消息重发
* @return
*/
public Boolean reSend(){
return false;
}
}
/**
* 消息发送实体类
*/
class MSGS implements Serializable {
private MSG MSG;
public MSG getMSG() {
return MSG;
}
public void setMSG(MSG MSG) {
this.MSG = MSG;
}
}
class MSG {
/**
* 具体消息头部信息
*/
private HEADER HEADER;
/**
* 具体消息支持JSON字符串或者XML
*/
private String BODY;
public HEADER getHEADER() {
return HEADER;
}
public void setHEADER(HEADER HEADER) {
this.HEADER = HEADER;
}
public String getBODY() {
return BODY;
}
public void setBODY(String BODY) {
this.BODY = BODY;
}
}
/**
* 消息发送头部信息
*/
class HEADER {
/**
* 消息唯一标识,可以是ID
*/
private long SEQNO;
/**
* 发送的消息大类,在总线系统配置好后,分配给消息生产者
*/
private String TYPE;
/**
* 发送的消息子类,在总线系统配置好后,分配给消息生产者
*/
private String STYPE;
/**
* 消息增删改类型(IE=insert event,UE=update event,DE=delete event)
*/
private String OPTYPE;
/**
* 发送时间(如:20210320101421/yyyyMMddHHmmss)
*/
private String DDTM;
/**
* 你的账号名称
*/
private String SNDR;
/**
* 消息接收者
*/
private String RCVR;
public long getSEQNO() {
return SEQNO;
}
public void setSEQNO(long SEQNO) {
this.SEQNO = SEQNO;
}
public String getTYPE() {
return TYPE;
}
public void setTYPE(String TYPE) {
this.TYPE = TYPE;
}
public String getSTYPE() {
return STYPE;
}
public void setSTYPE(String STYPE) {
this.STYPE = STYPE;
}
public String getOPTYPE() {
return OPTYPE;
}
public void setOPTYPE(String OPTYPE) {
this.OPTYPE = OPTYPE;
}
public String getDDTM() {
return DDTM;
}
public void setDDTM(String DDTM) {
this.DDTM = DDTM;
}
public String getSNDR() {
return SNDR;
}
public void setSNDR(String SNDR) {
this.SNDR = SNDR;
}
public String getRCVR() {
return RCVR;
}
public void setRCVR(String RCVR) {
this.RCVR = RCVR;
}
}
/**
* 收发送接口返回结果实体类
*/
class ResultJson<T> implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 状态码 正确为200,其他为异常
*/
private String code;
/**
* 结果描述
*/
private String msg;
/**
* 结果数据
*/
private T data;
}
... ...