Java-springboot基于分布式存储的仿小米卡包优惠券后台系统(一)商户投放系统
系统工程环境搭建
(一)创建工程
修改依赖和添加依赖
修改springboot版本依赖为1.5.3
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<?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.imooc.passbook</groupId>
<artifactId>merchants</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>merchants</name>
<description>passbook of merchants</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</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-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.31</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<version>1.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.2</version>
</dependency>
</dependencies>
<build>
<finalName>Merchants</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
在启动springboot时候会报错是因为加入JDBC依赖后却没有指定相关的数据库连接,所以得在application.properties中配置数据库的连接信息,但我会改成application.yml
spring:
application:
name: Merchants
datasource:
url: jdbc:mysql://127.0.0.1:3306/passbook?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 12345678
driver-class-name: com.mysql.cj.jdbc.Driver
kafka:
bootstrap-servers: 127.0.0.1:9092
consumer:
group-id: passbook
listener:
concurrency: 4
server:
port: 9527
logging:
level: debug
file: merchants.log
在IDEA中使用DateBase就能代替Navicat for MySQL连接服务器,具体的登录操作和Navicat的大相径庭
(二)在resources中创建一个merchantSQL表,存储商户信息的表并在数据库中创建passbook数据库,不然启动springboot的时候会报错,提示找不到passbook数据库
CREATE TABLE `merchants` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(64) COLLATE utf8_bin NOT NULL COMMENT '商户名称',
`logo_url` varchar(256) COLLATE utf8_bin NOT NULL COMMENT '商户 logo',
`business_license_url` varchar(256) COLLATE utf8_bin NOT NULL COMMENT '商户营业执照',
`phone` varchar(64) COLLATE utf8_bin NOT NULL COMMENT '商户联系电话',
`address` varchar(64) COLLATE utf8_bin NOT NULL COMMENT '商户地址',
`is_audit` BOOLEAN NOT NULL COMMENT '是否通过审核',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8;
(三)定义常量类:在constant中创建Constant,ErrorCode,TemplateColor分别定义通用的定义常量类,错误码枚举定义类,卡券的背景色
package com.hyb.passbook.merchants.constant;
/**
* 描述 : 通用的定义常量类
*/
public class Constant {
/**
* 商户优惠券投放的 kafka Topic
*/
public static final String TEMPLATE_TOPIC = "merchants-template";
/**
* 通用的商户token,key
*/
public static final String TOKEN_STRING = "token";
/**
* 实际颁发商户的token,value
*/
public static final String TOKEN = "passbook-merchants";
}
package com.hyb.passbook.merchants.constant;
/**
* 描述:错误码枚举定义
*/
public enum ErrorCode {
SUCCESS(0,""),
DUPLICATE_NAME(1,"商户名称重复"),
EMPTY_LOGO(2,"商户logo为空"),
EMPTY_BUSINESS_LICENSE(3,"商户营业执照为空"),
ERROR_PHONE(4,"商户联系电话为空"),
EMPTY_ADDRESS(5,"商户地址为空"),
MERCHANTS_NOT_EXIST(6,"商户不存在");
private Integer code;
private String desc;
ErrorCode(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
public Integer getCode() {
return code;
}
public String getDesc() {
return desc;
}
}
package com.hyb.passbook.merchants.constant;
/**
* 描述 : 卡券的背景色
*/
public enum TemplateColor {
RED(1,"红色"),
GREED(2,"绿色"),
BULE(3,"蓝色");
//颜色代码
private Integer code;
//颜色描述
private String color;
TemplateColor(Integer code, String color) {
this.code = code;
this.color = color;
}
public Integer getCode() {
return code;
}
public String getColor() {
return color;
}
}
(四)权限校验
创建security,新建AccessContext,用ThreadLocal 去单独存储每个线程携带的 Token信息
package com.hyb.passbook.merchants.security;
/**
1. 描写:用ThreadLocal 去单独存储每个线程携带的 Token信息
*/
public class AccessContext {
private static final ThreadLocal<String> token = new ThreadLocal<String>();
//获取String类型的token
public static String getToken() {
return token.get();
}
public static void setToken(String tokenStr){
token.set(tokenStr);
}
//用户remove掉当前token的信息
public static void clearAccessKey(){
token.remove();
}
}
(五)创建拦截器
- 实现拦截器接口
- 将拦截器注入到spring中
- 编写token拦截器的业务逻辑
- 最后释放token
package com.hyb.passbook.merchants.security;
import com.hyb.passbook.merchants.constant.Constant;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 描述:权限的拦截器
* 是一个spring bean 需要注入到spring中
*/
@Component
public class AuthCheckIntercepter implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
String token = httpServletRequest.getHeader(Constant.TOKEN_STRING);
if (StringUtils.isEmpty(token)) {
throw new Exception("Header 中缺少 " + Constant.TOKEN_STRING + "!");
}
if(!token.equals(Constant.TOKEN)){
throw new Exception("Header 中 "+ Constant.TOKEN_STRING + "错误!");
}
AccessContext.setToken(token);
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
AccessContext.clearAccessKey();
}
}