springboot2.x+security+vue2.x后台管理框架---后端搭建(一)
后端搭建
一、技术选型
1、springboot2.7.x
2、security
3、vue2.x
二、springboot基础配置
1、引入依赖
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.longzy</groupId>
<artifactId>longzy-admin</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>longzy-admin</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<mysql.version>5.1.41</mysql.version>
<log4j.version>2.17.2</log4j.version>
<fastjson.version>1.2.80</fastjson.version>
<mybatis.version>2.2.2</mybatis.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--mysql 依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.3</version>
</plugin>
</plugins>
</build>
</project>
2、application.yml配置
# 上下文、端口配置
server:
port: 8087
servlet:
context-path: /longzy
# 数据源配置
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/longzy?useUnicode=true&useSSL=false&characterEncoding=utf8
username: root
password: root
# 启动图标配置
banner:
location: banner.txt
#热部署
devtools:
restart:
enabled: true
# mybatis配置
mybatis:
mapper-locations:
- classpath:mapper/read/*.xml
- classpath:mapper/write/*.xml
configuration:
# sql日志打印
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
三、全局配置
1、全局统一返回格式
package com.longzy.common.response;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @Desc: 统一返回格式
* @Packge: com.longzy.common.response
* @Author: longzy
* @Date: 2022/9/2 14:36
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CommonReturnType implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 返回code
*/
private long code;
/**
* 返回信息
*/
private String message;
/**
* 返回数据
*/
private Object data;
/**
* 成功返回
* @param message 返回的信息
* @return
*/
public static CommonReturnType success(String message){
return new CommonReturnType(200, message, null);
}
/**
* 成功
* @param message 成功信息
* @param data 数据
* @return
*/
public static CommonReturnType success(String message, Object data){
return new CommonReturnType(200, message, data);
}
/**
* 失败
* @param message 失败信息
* @return
*/
public static CommonReturnType error(String message){
return new CommonReturnType(500, message, null);
}
/**
* 失败
* @param message 失败信息
* @param data 失败数据
* @return
*/
public static CommonReturnType error(String message, Object data){
return new CommonReturnType(500, message, data);
}
}
2、全局异常配置
(1)、CommonError错误类接口定义
package com.longzy.error;
/**
* @Desc: 错误类接口
* @Packge: com.longzy.error
* @Author: longzy
* @Date: 2022/9/2 15:15
*/
public interface CommonError {
// 错误码
public long getErrCode();
// 错误信息
public String getErrMsg();
// 设置错误信息,返回错误具体子类
public CommonError setErrMsg(String errMsg);
}
(2)、EmBusinessError错误类枚举
package com.longzy.error;
import lombok.Data;
/**
* @Desc:
* @Packge: com.longzy.error
* @Author: longzy
* @Date: 2022/9/2 15:16
*/
public enum EmBusinessError implements CommonError {
// 通用错误类型10001
PARAMETER_VALIDATION_ERROR(10001, "参数错误,请联系系统管理员."),
SYSTEM_ERROR(10002,"系统错误,请联系系统管理员."),
UNKNOWN_ERROR(10003, "未知错误,请联系系统管理员."),
BIND_ERROR(10004, "参数校验错误,请联系系统管理员."),
CUSTOM_ERROR(10005, "自定义错误,请联系系统管理员.")
;
// 错误码
private long errCode;
// 错误信息
private String errMsg;
EmBusinessError(long errCode, String errMsg){
this.errCode = errCode;
this.errMsg = errMsg;
}
@Override
public long getErrCode() {
return this.errCode;
}
public void setErrCode(long errCode) {
this.errCode = errCode;
}
@Override
public String getErrMsg() {
return this.errMsg;
}
@Override
public CommonError setErrMsg(String errMsg) {
this.errMsg = errMsg;
return this;
}
}
(3)、BusinessException业务异常类
package com.longzy.error;
/**
* @Desc: 业务错误类
* @Packge: com.longzy.error
* @Author: longzy
* @Date: 2022/9/2 15:16
*/
public class BusinessException extends RuntimeException implements CommonError{
private CommonError commonError;
// 直接接收EmBusinessError的传参用于构造业务异常
public BusinessException(CommonError commonError){
super();
this.commonError = commonError;
}
// 接收自定义的errMsg的方法构造业务异常
public BusinessException(CommonError commonError, String errMsg){
super();
this.commonError = commonError;
this.commonError.setErrMsg(errMsg);
}
public BusinessException(String errMsg){
super(errMsg);
}
@Override
public long getErrCode() {
return this.commonError.getErrCode();
}
@Override
public String getErrMsg() {
return this.commonError.getErrMsg();
}
@Override
public CommonError setErrMsg(String errMsg) {
return this.commonError.setErrMsg(errMsg);
}
public CommonError getCommonError() {
return commonError;
}
}
(4)、GlobalExceptionHandler全局异常类
package com.longzy.error.handle;
import com.longzy.error.BusinessException;
import com.longzy.error.EmBusinessError;
import com.longzy.common.response.CommonReturnType;
import org.omg.CORBA.SystemException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
import java.util.stream.Collectors;
/**
* @Desc: 全局异常处理
* @Packge: com.longzy.error.handle
* @Author: longzy
* @Date: 2022/9/2 15:16
*/
@ControllerAdvice
public class GlobalExceptionHandler {
// 日志
public static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(Exception.class)
@ResponseBody
public CommonReturnType doError(Exception ex){
ex.printStackTrace();
CommonReturnType commonReturnType = new CommonReturnType();
if (ex instanceof BusinessException){
BusinessException businessException = (BusinessException) ex;
commonReturnType.setCode(EmBusinessError.CUSTOM_ERROR.getErrCode());
commonReturnType.setMessage(businessException.getMessage());
}else if (ex instanceof IllegalArgumentException){ // 参数异常
commonReturnType.setCode(EmBusinessError.PARAMETER_VALIDATION_ERROR.getErrCode());
commonReturnType.setMessage(EmBusinessError.PARAMETER_VALIDATION_ERROR.getErrMsg());
}else if (ex instanceof SystemException) { // 系统错误异常
commonReturnType.setCode(EmBusinessError.SYSTEM_ERROR.getErrCode());
commonReturnType.setMessage(EmBusinessError.SYSTEM_ERROR.getErrMsg());
}else if (ex instanceof BindException){ // 参数校验异常
BindException bindException = (BindException) ex;
List<String> collect = bindException.getFieldErrors().stream()
.map(o -> o.getDefaultMessage())
.collect(Collectors.toList());
commonReturnType.setCode(EmBusinessError.BIND_ERROR.getErrCode());
commonReturnType.setMessage(collect.toString());
}else { // 未知错误
commonReturnType.setCode(EmBusinessError.UNKNOWN_ERROR.getErrCode());
commonReturnType.setMessage(EmBusinessError.UNKNOWN_ERROR.getErrMsg());
}
logger.error(commonReturnType.toString());
return commonReturnType;
}
}
四、swagger和knife4j整合配置
1,引入依赖
<swagger.version>3.0.0</swagger.version>
<knife4j.version>3.0.3</knife4j.version>
<!--swagger3-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>${swagger.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.xiaoymin/knife4j-spring-boot-starter -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>${knife4j.version}</version>
</dependency>
2、SwaggerConfig配置
package com.longzy.config;
import io.swagger.annotations.Api;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
/**
* @Desc:
* @Packge: com.longzy.config
* @Author: longzy
* @Date: 2022/5/21 11:50
*/
//@EnableOpenApi
@Configuration
public class SwaggerConfig {
// http://localhost:8087/longzy/swagger-ui/index.html 原ui路径
// http://localhost:8087/longzy/doc.html knife4j路径
// 配置swagger3核心配置docket
@Bean
public Docket createRestApi(){
return new Docket(DocumentationType.OAS_30) // 指定api的类型为swagger3
// 文档信息配置
.apiInfo(apiInfo())
// 配置扫描的接口
.select()
// 配置扫描哪里的接口
.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
// 过滤请求,只扫描请求以/category开头的接口
.paths(PathSelectors.any())
.build()
.enable(true);
}
private ApiInfo apiInfo(){
return new ApiInfoBuilder() // 接口的信息建造者
.title("longzy 接口api文档") // 文档页标题
.contact(new Contact("longzy",
"",
"258xxxxxx@qq.com")) // 联系人信息
.version("1.0")
.description("longzy 提供的api文档") // 详细信息
.build();
}
}
访问 http://localhost:8087/longzy/doc.html ,出现如图所示: