上一篇介绍文章
https://blog.csdn.net/weixin_45206218/article/details/127872136
代码仓库
https://gitee.com/stevezhaozps/daily-weather
前期准备
- 一台云服务器
- 云服务器安装MySQL8.x
- 云服务器安装jdk8
数据库初始化
由于本项目使用的是springdatajpa,所以不需要我们手动建表,只需要建数据库启动项目,会自动建表
CREATE DATABASE daily_weather;
这里提供数据库备份
/*
Navicat Premium Data Transfer
Source Server : win11
Source Server Type : MySQL
Source Server Version : 50740 (5.7.40-log)
Source Host : localhost:3306
Source Schema : daily_weather
Target Server Type : MySQL
Target Server Version : 50740 (5.7.40-log)
File Encoding : 65001
Date: 17/11/2022 15:03:50
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user_info
-- ----------------------------
DROP TABLE IF EXISTS `user_info`;
CREATE TABLE `user_info` (
`id` bigint(20) NOT NULL,
`bir_time` datetime NULL DEFAULT NULL,
`city` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
`create_time` datetime NULL DEFAULT NULL,
`district_id` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
`nickname` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
`scq_time` datetime NULL DEFAULT NULL,
`type` int(11) NULL DEFAULT NULL,
`update_time` datetime NULL DEFAULT NULL,
`wechat_id` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = MyISAM CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
项目配置
如何申请见上一篇文章
server:
port: 43310
# 微信配置
tencent:
wechat:
appId: 微信申请appid
appSecret: 微信申请appSecret
# 模板消息集合
templatelist:
- type: 1
templateId: 模板id
- type: 2
templateId: 模板id
- type: 3
templateId: 模板id
# 百度天气配置
baidu:
server: https://api.map.baidu.com
ak: 百度申请的ak
# 天行数据
tianxin:
server: http://api.tianapi.com
key: 天行数据的key
spring:
mvc:
pathmatch:
matching-strategy: ant_path_matcher
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/daily_weather?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: 数据库用户
password: 数据库密码
hikari:
minimum-idle: 5
# 空闲连接存活最大时间,默认600000(10分钟)
idle-timeout: 180000
# 连接池最大连接数,默认是10
maximum-pool-size: 10
# 此属性控制从池返回的连接的默认自动提交行为,默认值:true
auto-commit: true
# 连接池名称
pool-name: MyHikariCP
# 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟
max-lifetime: 1800000
# 数据库连接超时时间,默认30秒,即30000
connection-timeout: 30000
connection-test-query: SELECT 1
jpa:
show-sql: true # 默认false,在日志里显示执行的sql语句
database: mysql
database-platform: org.hibernate.dialect.MySQL5Dialect
hibernate:
ddl-auto: update #指定为update,每次启动项目检测表结构有变化的时候会新增字段,表不存在时会 新建,如果指定create,则每次启动项目都会清空数据并删除表,再新建
naming:
#指定jpa的自动表生成策略,驼峰自动映射为下划线格式7
implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
#physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
# 日志
#logging:
# config: classpath:logback-spring-dev.xml
项目结构介绍
- advice : 负责统一封装处理前端返回数据格式
- common : 统一结果封装
- config: 项目配置
- domain: 实体类
- enums: 服务状态枚举类
- exception: 异常处理和自定义异常
- job: 定时任务
- remote: 第三方接口调用,使用openfeign
- repository: 数据库操作层,dao/mapper层
- rest: 视图控制层
- service: 业务处理层
统一结果封装
注意返回String类型需要特殊处理
package com.zhao.wechat.advice;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zhao.wechat.common.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
/**
* 对前端响应结果统一封装
*/
@Slf4j
@RestControllerAdvice(basePackages = {"com.zhao.wechat.rest"})
public class ApiResponseAdvice implements ResponseBodyAdvice<Object> {
/**
* 打印统一请求响应规范
*/
ApiResponseAdvice(){
log.info("启动请求统一响应规范... ...");
}
/**
* 判断是否需要对返回值进行封装
* @param returnType the return type
* @param converterType the selected converter type
* @return
*/
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
// 如果返回的结果是Result.class类型就不用封装
if (returnType.getParameterType().equals(Result.class)){
return false;
}
return true;
}
/**
* 对返回前端的值统一封装
* @param body the body to be written
* @param returnType the return type of the controller method
* @param selectedContentType the content type selected through content negotiation
* @param selectedConverterType the converter type selected to write to the response
* @param request the current request
* @param response the current response
* @return
*/
@Override
public Object beforeBodyWrite(Object body,
MethodParameter returnType,
MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request,
ServerHttpResponse response) {
if (returnType.getParameterType().equals(String.class)){
// 如果是String类需要特殊处理
ObjectMapper objectMapper = new ObjectMapper();
try {
// 设置响应数据格式为json
response.getHeaders().add("content-type","application/json;charset=UTF-8");
return objectMapper.writeValueAsString(Result.success(body));
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
return Result.success(body);
}
}
项目打包
- 找到maven
- 先点clean清理,再点package打包
在target找到jar包,准备上传到云服务器
项目部署
xftp 上传文件 + xshell
通过xftp上传到云服务器
xshell执行jar
切换到当前jar目录下
# 启动
java -jar daily-weather-1.0.0.jar >/dev/null 2&1 &
# 启动成功会出现log目录,cd到log目录下可查看项目运行日志,有无报错
# 查看项目是否在运行
ps -ef | grep daily-weather-1.0.0.jar
# 可看到线程的pid
kill -9 pid号,可以杀死当前运行的项目
通过swagger访问
正常启动成功后,使用公网ip:端口/doc.html可以访问swagger页面