目录
2.后端工程的application.properties配置文件
1.后端工程的pom文件
<!--springboot工程web开发启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mybatisplus开发启动器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
<!--devtools热启动工具(修改Java代码后无需重启, 只需maven编译即可)-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!--mysql驱动包, 降低版本到5.1.47-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
<scope>runtime</scope>
</dependency>
<!--lombok (实体类注解, @Sl4j日志注解)-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--jwt (创建和校验token令牌)-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
<!--springboot单元测试依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
2.后端工程的application.properties配置文件
application.properties
spring.application.name=back
spring.profiles.active=dev
logging.config=classpath:log.xml
application-dev.properties
server.port=8888
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.name=defaultDataSource
spring.datasource.url=jdbc:mysql://localhost:3306/shop?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
mybatis-plus.type-aliases-package=com.example.back.entity
mybatis-plus.configuration.auto-mapping-behavior=fu
application-prod.properties
3.准备日志的配置文件
4.创建工程子包
创建在src/main/java/com.example.shopback中
-
config (配置类包)
-
controller (控制器包)
-
entity (实体类包)
-
exception (全局异常处理包)
-
interceptor (拦截器包)
-
mapper (mybatisplus接管的mapper层接口包)
-
page (自定义的分页器包)
-
response (自定义的统一返回数据格式包)
-
service (业务层包)
-
util (工具包)
创建在src/main/resources中
mapper (用来编写SQL语句的mapper.xml文件目录)
添加src/main/resources目录中的xml文件打包的配置
<build>
..........
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</build>
5.创建配置类
创建MyBatisPlusConfig配置类
这个配置类的作用是配置分页的时候SQL语句使用MySQL的limit语法
@Configuration
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
mybatisPlusInterceptor.addInnerInterceptor(paginationInnerInterceptor);
return mybatisPlusInterceptor;
}
}
创建CrossOriginConfig跨域配置类
@Configuration
public class CrossOriginConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedHeaders("*")
.allowedMethods("*")
.allowCredentials(true);
WebMvcConfigurer.super.addCorsMappings(registry);
}
}
创建InterceptorConfig拦截器配置类
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
}
}
6.创建统一返回数据相关类
创建响应信息枚举类ResponseMsg
信息代码code和信息内容msg参考了《阿里巴巴开发手册》
枚举类型ResponseMsg可以作为变量的数据类型
SUCCESS("000000", "一切ok") 这行代码等同于
public static final ResponseMsg SUCCESS = new ResponseMsg("000000", "一切ok");
public enum ResponseMsg {
SUCCESS("000000", "一切ok"),
USER_ALREADY_EXIST("A0111","用户名已存在"),
USER_NOT_EXIST("A0201","用户账户不存在"),
PASSWORD_ERROR("A0210","用户密码错误"),
TOKEN_ERROR("A0220","用户令牌失效"),
SYSTEM_ERROR("B0001","系统执行出错"),
DATABASE_ERROR("C0300","数据库服务出错");
private String code;
private String msg;
ResponseMsg(String code, String msg){
this.code = code;
this.msg = msg;
}
public String getCode() {
return code;
}
public String getMsg() {
return msg;
}
}
创建统一响应数据封装类ResponseData
这个类用于Rest风格的控制器中方法的返回值类型
也就是说所有的Rest风格的控制器中的方法全部统一返回ResponseData类型
因为Rest风格的控制器不做转发和重定向,只需返回json格式的数据给前端的ajax
这个相对于用ResponseData类统一了json数据的格式
该类有三个成员变量
code 信息代码
msg 信息内容
data 响应数据
该类有两个静态方法
success() 接收一个Object类型的任意对象作为参数(改参数就是返回的数据), 返回一个请求成功的结果, 携带数据, json格式大概是这样的
{
"code": "000000",
"msg" "一切ok",
"data": 任意类型的数据
}
failure() 接收一个枚举类型ResponseMsg作为参数(该类型包含code和msg), 返回一个请求失败的结果, 携带错误信息, json格式大概是这样的
{
"code": 枚举的任意信息代码,
"msg" 枚举的任意信息内容
}
@Data
public class ResponseData {
private String code;
private String msg;
private Object data;
public static ResponseData success(Object data){
ResponseData responseData = new ResponseData();
responseData.setCode(ResponseMsg.SUCCESS.getCode());
responseData.setMsg(ResponseMsg.SUCCESS.getMsg());
responseData.setData(data);
return responseData;
}
public static ResponseData failure (ResponseMsg responseMsg){
ResponseData responseData = new ResponseData();
responseData.setCode(responseMsg.getCode());
responseData.setMsg(responseMsg.getMsg());
return responseData;
}
}
创建统一的自定义运行时异常类CustomException
这个类中有一个ResponseMsg枚举类型的成员变量
提供构造方法和get方法
public class CustomException extends RuntimeException{
private ResponseMsg responseMsg;
public CustomException(ResponseMsg responseMsg){
super(responseMsg.getCode() + ":" + responseMsg.getMsg());
this.responseMsg = responseMsg;
}
public ResponseMsg getResponseMsg() {
return responseMsg;
}
}
7.创建统一的全局异常处理器类
这个类使用了@RestControllerAdvice注解, 该注解是基于AOP面向切面, 代理了全局任意地方的异常捕捉和处理, 也就说, 无论是娜个拦截器,控制器,Srevice,Mapper, ......中任何方法中出现了异常,都会被这个类捕捉到
那么有了这个全局异常处理器, 我们就可以优雅的处理程序中的异常, 不需要自己写try...catch
也不需要throws向上抛出
这个类中有两个方法
-
customExceptionHandler() 这个方法用于捕捉和处理我们自定义的异常CustomException
-
globalExceptionHandler() 这个方法用于捕捉和处理除了我们自定义的异常之外所有的其他异常
@Slf4j
@RestControllerAdvice
public class GlobalExceptionAdvice {
@ExceptionHandler({CustomException.class})
public ResponseData customExceptionHandler(CustomException e) {
e.printStackTrace();
return ResponseData.failure(e.getResponseMsg());
}
@ExceptionHandler({Exception.class})
public ResponseData globalExceptionHandler(Exception e) {
log.error(e.getMessage(), e);
if (e instanceof SQLException){
return ResponseData.failure(ResponseMsg.DATABASE_ERROR);
}else {
return ResponseData.failure(ResponseMsg.SYSTEM_ERROR);
}
}
}
8.创建用户身份令牌工具类TokenUtil
注意: 需要安装jwt依赖
需要有User实体类 (包含id和username属性即可)
public class TokenUtil {
private static final String secret = "!A@B#F$G%K^U&E*L";
private static Algorithm getAlg(){
return Algorithm.HMAC256(secret);
}
public static String getToken(User user){
System.out.println(user);
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND,60 * 30);
return JWT.create()
.withClaim("id", user.getId())
.withClaim("username", user.getUsername())
.withExpiresAt(calendar.getTime())
.sign(getAlg());
}
public static User verityToken(String token){
User user = new User();
DecodedJWT jwt = JWT.require(getAlg()).build().verify(token);
user.setId(Integer.parseInt(jwt.getClaim("id").asString()));
user.setUsername(jwt.getClaim("username").asString());
return user;
}
}
9.创建用户身份令牌拦截器类
public class TokenInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getHeader("token");
try {
TokenUtil.verityToken(token);
}catch (Exception e){
e.printStackTrace();
throw new CustomException(ResponseMsg.TOKEN_ERROR);
}
return true;
}
}
用户身份令牌拦截器类创建好以后, 要去拦截器配置类中配置一下拦截地址和放行地址
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new TokenInterceptor())
.addPathPatterns("/api/**")
.excludePathPatterns("/api/user/login");
}
}
10.创建实体类
BaseEntity 实体类父类
@Data
public class BaseEntity {
@TableId(type = IdType.AUTO)
private Integer id;
private Integer isDelete;
private String createDate;
private String modifyDate;
}
User 用户实体类继承BaseEntity
@Data
public class User extends BaseEntity{
private String username;
private String sex;
private String mobile;
private String idCode;
private String avatar;
private String password;
private String idCardFront;
private String idCardBack;
@TableField(exist = false)
private String token;
}
实体类中的命名与数据库表中的命名满足驼峰和全小写加_连字符的规范, 就不需要添加
@TableField注解进行名称映射,如果不满足规范,需要添加注解映射
其他实体类省略........
11.创建Mapper接口和Mapper.xml文件
UserMapper接口
public interface UserMapper extends BaseMapper<User> {
}