springboot 2.x, yml或properties,内置tomcat
api-controller,
common - utils ,
mapper - sql ,
generator - mybatis逆向工程,
pojo - 表的实体映射,
service - 服务,
web - 前端页面
跟父级工程一样不选择模板,创建SuperMarket-common,
创建子模块后,默认的打开方式为jar包,无需显示指定
创建好工程后,查看父级工程pom中是否存在子模块的配置项
点击finish,完成工程的创建,打开web的pom,将其他的删除,留下如下就行了
pojo -> common, 在pojo的pom中添加如下依赖
com.lzy
SuperMarket-common
1.0-SNAPSHOT
mapper -> pojo, 在mapper的pom中添加如下依赖
com.lzy
SuperMarket-pojo
1.0-SNAPSHOT
service -> mapper, 在service的pom中添加如下依赖
com.lzy
SuperMarket-mapper
1.0-SNAPSHOT
api -> service ,在api的pom中添加如下依赖
com.lzy
SuperMarket-service
1.0-SNAPSHOT
web -> api , 在web的pom中添加如下依赖
com.lzy
SuperMarket-api
1.0-SNAPSHOT
配置好后,使用父级工程的maven-install将所有模块进行安装安装完成之后模块之间才能相互依赖调用,在顶层项目中,install即可,出现下面信息即为安装成功:
org.springframework.boot
spring-boot-starter-parent
2.1.5.RELEASE
UTF-8
UTF-8
1.8
org.springframework.boot
spring-boot-starter
org.springframeork.boot
spring-boot-starter-logging
ch.qos.logback
logback-classic
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-configuration-processor
true
在web的resources下创建
在application.properties中添加配置端口
#配置端口号
#配置服务器端口
server.port=8088
server.tomcat.uri-encoding=utf-8
server.max-http-header-size=80KB
server.servlet.context-path=/
/ / 启动类
@SpringBootApplication // 扫描所有包
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
//controller + ResponseBody
@RestController
public class TestController {
// 指定接收一个get请求
@GetMapping("/test")
public Object test(){
return "success";
}
}
找到父级工程进行install
执行application
测试环境,出现下述内容即为配置成功
mysql
mysql-connector-java
5.1.41
org.mybatis.spring.boot
mybatis-spring-boot
2.1.0
在application.properties中配置
#配置数据源
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/gues?useUnicode=true&characterEncoding=UTF-8&autoReconnect
spring.datasource.username=root
spring.datasource.password=root
#等待连接池分配连接的最大时长,超过之后不发生连接
spring.datasource.hikari.connection-timeout=30000
#最小连接数
spring.datasource.hikari.minimum-idle=5
#最大连接数
spring.datasource.hikari.maximum-pool-size=20
#自动提交配置
spring.datasource.hikari.auto-commit=true
#连接超时时间
spring.datasource.hikari.idle-timeout=1000000
spring.datasource.hikari.connection-test-query=SELECT 1
#指定pojo类所在包
mybatis.type-aliases-package=com.lzy.pojo
#配置mybatis
mybatis.mapper-locations=classpath:mapper/*.xml
#配置sql打印
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
在父级pom中加入mapper的逆向工具
tk.mybatis
mapper-spring-boot-starter
2.1.5
在逆向工程pom中添加
org.springframework.boot
spring-boot-maven-plugin
org.mybatis.generator
mybatis-generator-maven-plugin
1.3.2
org.mybatis.generator
mybatis-generator-core
1.3.5
mysql
mysql-connector-java
5.1.41
mybatis.generator
package
generate
true
true
src/main/resources/mybatis-generator.xml
// 启动类
@SpringBootApplication // 扫描所有包
@MapperScan(basePackages = "com.lzy.mapper")
@ComponentScan(basePackages = {"com.lzy"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
io.springfox
springfox-swagger2
2.4.0
io.springfox
springfox-swagger-ui
2.4.0
在Swagger2中配置
package com.lzy.config;
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.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class Swagger2 {
// http://localhost:8088/swagger-ui.html 原ui路径
// 配置swagger2核心配置docket
@Bean
public Docket createRestApi(){
return new Docket(DocumentationType.SWAGGER_2) // 指定api的类型为swagger2
.apiInfo(apiInfo()) // 用于定义api文档汇总信息,页面显示的文案材料
.select()
.apis(RequestHandlerSelectors.basePackage("com.lzy.controller")) // 指定controller包
.paths(PathSelectors.any()) // 所有的controller包
.build();
}
private ApiInfo apiInfo(){
return new ApiInfoBuilder() // 接口的信息建造者
.title("超市系统平台 接口api") // 文档页标题
.contact(new Contact("lzy",
"https://github.com/longzy-hub/SuperMarket",
"[email protected]")) // 联系人信息
.description("为贵工程超市系统平台提供的api文档") // 详细信息
.termsOfServiceUrl("https://github.com/longzy-hub/SuperMarket") // 网站地址
.build();
}
}
测试路径:
http://localhost:8088/swagger-ui.html
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-logging
org.slf4j
slf4j-api
1.7.21
org.slf4j
slf4j-log4j12
1.7.21
#设置日志输出的等级为debug,低于debug就不会输出了
#设置日志输出到两种地方,分别叫做 stdout和 file 控制台输出和文件输出
log4j.rootLogger=DEBUG,stdout,file
log4j.additivity.org.apache=true
#第一个地方stdout, 输出到控制台
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.threshold=INFO
#设置输出格式%5p [%t] (%F:%L) - %m%n
#宽度是5的优先等级 线程名称 (文件名:行号) - 信息 回车换行
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%-5p %c{1}:%L - %m%n
#以文件形式滚动输出
log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.DatePattern='.'yyyy-MM-dd-HH-mm
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
log4j.appender.file.Threshold=INFO
log4j.appender.file.append=true
log4j.appender.file.File=E:/ideapro/log/SuperMarket/mylog.log
package com.lzy.response;
// 通用返回格式json
public class CommonReturnType {
// 表明对应请求的返回处理结果“success” 和 "fail"
private String status;
// 若status=success,则data内返回前端需要的json数据
// status=fail ,则data内使用通用的错误码格式
private Object data;
public static CommonReturnType create(Object result, String status){
CommonReturnType type = new CommonReturnType();
type.setStatus(status);
type.setData(result);
return type;
}
// 创建一个通用的创建方法
public static CommonReturnType success(Object result){
return CommonReturnType.create(result,"success");
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
package com.lzy.error;
// 错误类的接口定义
public interface CommonError {
// 错误码
public int getErrCode();
// 错误信息
public String getErrMsg();
// 设置错误信息,返回错误具体子类
public CommonError setErrMsg(String errMsg);
}
package com.lzy.error;
public enum EmBusinessError implements CommonError {
// 通用错误类型10001
PARAMETER_VALIDATION_ERROR(10001, "参数错误"),
SYSTEM_ERROR(10002,"系统错误"),
UNKNOWN_ERROR(10003, "未知错误")
;
EmBusinessError(int errCode, String errMsg){
this.errCode = errCode;
this.errMsg = errMsg;
}
// 错误码
private int errCode;
// 错误信息
private String errMsg;
@Override
public int getErrCode() {
return this.errCode;
}
public void setErrCode(int errCode) {
this.errCode = errCode;
}
@Override
public String getErrMsg() {
return this.errMsg;
}
@Override
public CommonError setErrMsg(String errMsg) {
this.errMsg = errMsg;
return this;
}
}
package com.lzy.error;
// 包装器业务异常类实现
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);
}
@Override
public int 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;
}
}
package com.lzy.error.handler;
import com.lzy.error.BusinessException;
import com.lzy.error.EmBusinessError;
import com.lzy.response.CommonReturnType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
// 全局异常处理
@ControllerAdvice
public class GlobalExceptionHandler {
// 日志
public static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(Exception.class)
@ResponseBody
public CommonReturnType doError(HttpServletRequest httpServletRequest,//
HttpServletResponse httpServletResponse, Exception ex){
ex.printStackTrace();
Map responseData = new HashMap<>();
if (ex instanceof BusinessException){
BusinessException businessException = (BusinessException) ex;
responseData.put("errCode",businessException.getErrCode());
responseData.put("errMsg",businessException.getErrMsg());
}else {
responseData.put("errCode", EmBusinessError.UNKNOWN_ERROR.getErrCode());
responseData.put("errMsg", EmBusinessError.UNKNOWN_ERROR.getErrMsg());
}
logger.error(responseData.toString());
return CommonReturnType.create(responseData, "fail");
}
}
org.apache.commons
commons-lang3
3.4
org.hibernate
hibernate-validator
6.1.4.Final
org.projectlombok
lombok
1.18.4
cn.hutool
hutool-all
5.3.7
cn.hutool
hutool-parent
5.3.7
pom
package com.lzy.validator;
import org.apache.commons.lang3.StringUtils;
import java.util.HashMap;
import java.util.Map;
// 结果返回结构
public class ValidationResult {
// 校验结果是否有错
private boolean hasErrors = false;
// 存储错误信息的map
private Map errorMsgMap = new HashMap<>();
public boolean isHasErrors() {
return hasErrors;
}
public void setHasErrors(boolean hasErrors) {
this.hasErrors = hasErrors;
}
public Map getErrorMsgMap() {
return errorMsgMap;
}
public void setErrorMsgMap(Map errorMsgMap) {
this.errorMsgMap = errorMsgMap;
}
// 实现通用的通过格式化字符串信息获取错误结果的msg方法
public String getErrMsg(){
return StringUtils.join(errorMsgMap.values().toArray(),",");
}
}
package com.lzy.validator;
import com.lzy.error.BusinessException;
import org.springframework.beans.factory.InitializingBean;
// 校验器接口api
public interface ValidatorApi extends InitializingBean {
public void check(Object bean) throws BusinessException;
}
package com.lzy.validator.impl;
import cn.hutool.core.map.MapUtil;
import com.lzy.error.BusinessException;
import com.lzy.error.EmBusinessError;
import com.lzy.validator.ValidationResult;
import com.lzy.validator.ValidatorApi;
import org.springframework.stereotype.Component;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.Set;
@Component
public class ValidatorImpl implements ValidatorApi {
private Validator validator;
@Override
public void check(Object bean) throws BusinessException {
ValidationResult result = validator(bean);
if (MapUtil.isNotEmpty(result.getErrorMsgMap())){
if (result.isHasErrors()){
throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,//
result.getErrorMsgMap().toString());
}
}
}
private ValidationResult validator(Object bean) {
final ValidationResult result = new ValidationResult();
Set> constraintViolationSet = validator.validate(bean);
if (constraintViolationSet.size() > 0){
// 有错误
result.setHasErrors(true);
constraintViolationSet.forEach(constraintViolation -> {
String errMsg = constraintViolation.getMessage();
String propertyName = constraintViolation.getPropertyPath().toString();
result.getErrorMsgMap().put(propertyName,errMsg);
});
}
return result;
}
@Override
public void afterPropertiesSet() throws Exception {
// 将hibernate validator 通过工厂的初始化方法使其实例化
this.validator = Validation.buildDefaultValidatorFactory().getValidator();
}
}
package com.lzy.controller.viewobject;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
public class TestVo {
@NotNull
private Integer id;
@NotBlank
@Length(min = 1, max = 3, message = "名称长度在1到3个字之间")
private String name;
}
TestController-validatortest
@Resource
private ValidatorImpl validator;
@GetMapping("/validatetest")
public CommonReturnType testException(TestVo testVo) {
validator.check(testVo);
return CommonReturnType.create("success");
}
javax.servlet
jstl
org.apache.tomcat.embed
tomcat-embed-jasper
#配置jsp的访问路径
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
Hello World!
// 测试页面
@RequestMapping("/index.page")
public String indexPage(){
return "index";
}
github : https://github.com/longzy-hub/SuperMarket