pom.xml文件各标签详解
Maven项目中有一个最核心的文件:pom.xml 文件
pom.xml文件是Maven项目中的核心项目管理文件,主要用于描述项目的:项目描述、配置文件、依赖管理、构建信息管理、组织信息管理和licenses、开发者需要遵循的规则、缺陷管理系统、项目的url、项目的依赖性,以及其他所有的项目相关因素。pom.xml 文件中包含了许多标签,下来介绍一些pom.xml文件常用的标签
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
项目依赖导入与设置
springboot 启动类依赖
12345
springboot 测试类依赖
12345
springboot Web开发依赖(包括Tomcat和spring-webmvc)
12345
Lombok依赖(用来简化对类的操作包括:set方法、get方法以及构造函数等,只需要一个注解)
1234567
Mybatis-Plus依赖
123456
application.yml文件 配置Mybatis-Plus
123456789101112mybatis-plus: configuration: # mybatis-plus日志 控制台输出 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: # 逻辑删除 logic-delete-field: delFlag logic-delete-value: 1 logic-not-delete-value: 0 # id生成规则:数据库id自增 id-type: auto
MySql依赖
123456789101112
application.yml文件 配置数据库
1234567spring: # 数据库配置 datasource: url: jdbc:mysql://localhost:3306/mybatis-plus-crud-test?characterEncoding=utf-8&serverTimezone=Asia/Shanghai username: 数据库用户名 password: 数据库密码 driver-class-name: com.mysql.cj.jdbc.Driver
redis依赖
12345
fastjson依赖(可以将 Java对象 转换为 JSON格式,当然它也可以将 JSON字符串 转换为 Java对象)
123456
jwt依赖
123456
springboot devtools热部署依赖
12345678
SpringSecurity启动器
12345
打包跳过测试 插件
12345678
指定项目源码的 jdk 版本,编译后的 jdk 版本,以及编码 插件
1234567891011
swagger依赖
12345678910111213141516
完整 pom.xml文件
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
完整 application.yml文件
12345678910111213141516171819202122232425262728293031323334353637383940# 服务端口(不设置默认:8080)server: port: 8070spring: # 数据库配置 datasource: url: jdbc:mysql://localhost:3306/mybatis-plus-crud-test?characterEncoding=utf-8&serverTimezone=Asia/Shanghai username: 数据库用户名 password: 数据库密码 driver-class-name: com.mysql.cj.jdbc.Driver servlet: # 文件上传大小限制 multipart: max-file-size: 2MB max-request-size: 5MB # redis配置 redis: host: redis的地址 port: redis的端口(redis默认端口:6379)mybatis-plus: configuration: # mybatis-plus日志 控制台输出 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: # 逻辑删除 logic-delete-field: delFlag logic-delete-value: 1 logic-not-delete-value: 0 # id生成规则:数据库id自增 id-type: auto# 七牛云上传凭证 配置oss: accessKey: 七牛云的上传凭证 access key secretKey: 七牛云的上传凭证 secret key bucket: 存储数据使用的仓库名 bucket name qiniu_domain: 自定义域名
项目细节配置
设置主键自动增长
创建数据表的时候设置主键自增
实体字段中配置主键字段 增加注解@TableId(value = "id",type = IdType.AUTO) (如果上面application.yml文件中的mybatis-plus配置设置了id自增,则实体类可以不用设置字段自动增长,mybatis-plus自带雪花算法)
1234567@SuppressWarnings("serial")@TableName("user") // 标识表名public class User { @TableId // 标识主键ID //实体类可以不用设置字段自动增长,mybatis-plus自带雪花算法 private Long id;}
设置新增、更新自动填充功能(MP字段自动填充)
在实体类中,对需要进行自动填充的字段添加注解
12345678910111213141516171819@SuppressWarnings("serial")@Data@AllArgsConstructor@NoArgsConstructor@TableName("user") // 标识表名public class User { @TableField(fill = FieldFill.INSERT) //创建人的用户ID private Long createBy; @TableField(fill = FieldFill.INSERT) //创建时间 private Date createTime; @TableField(fill = FieldFill.INSERT_UPDATE) //更新人的用户ID private Long updateBy; @TableField(fill = FieldFill.INSERT_UPDATE) //更新时间 private Date updateTime;}
自定义类MyMetaObjectHandler,实现 MetaObjectHandler 接口,重写相应方法即刻
1234567891011121314151617181920212223242526272829303132/** * 配置MP字段自动填充:实现 MetaObjectHandler 接口,重写相应方法即刻 * * 如需实现字段自动填充,请给需要填充的字段添加注解,例:@TableField(fill = FieldFill.INSERT_UPDATE) 、 @TableField(fill = FieldFill.INSERT) */@Componentpublic class MyMetaObjectHandler implements MetaObjectHandler { // 配置MP字段自动填充:实现 MetaObjectHandler 接口,重写相应方法即刻 /** * 新增数据自动填充方法 * @param metaObject */ @Override public void insertFill(MetaObject metaObject) { System.out.println("进入MP自动填充 新增数据"); this.setFieldValByName("createBy", (long)3, metaObject); this.setFieldValByName("createTime", new Date(), metaObject); this.setFieldValByName("updateBy", (long)3, metaObject); this.setFieldValByName("updateTime", new Date(), metaObject); } /** * 更新数据自动填充方法 * @param metaObject */ @Override public void updateFill(MetaObject metaObject) { System.out.println("进入MP自动填充 更新数据"); this.setFieldValByName("updateBy", (long)3, metaObject); this.setFieldValByName("updateTime", new Date(), metaObject); }}
配置逻辑删除(实体类)
数据库中的逻辑删除字段 要与 application.yml中配置的逻辑删除字段一致
在实体类中的逻辑删除字段添加注解 @TableLogic
12345678910@SuppressWarnings("serial")@Data@AllArgsConstructor@NoArgsConstructor@TableName("user") // 标识表名public class User { //删除标志(0代表未删除,1代表已删除) @TableLogic // 逻辑删除 注释 private Integer delFlag;}
配置分页查询功能
1234567891011@Configurationpublic class MybatisPlusConfig { // MP支持 分页配置 @Bean public MybatisPlusInterceptor mybatisPlusInterceptor(){ MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor(); // 添加分页插件 mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor()); return mybatisPlusInterceptor; }}
自定义 统一响应类与响应code枚举类
响应code枚举类
1234567891011121314151617181920212223242526272829303132333435363738public enum AppHttpCodeEnum { SUCCESS(200, "操作成功"), // 成功 NEED_LOGIN(401, "需要登陆后操作"), // 登录 NO_OPERATOR_AUTH(403, "无权限操作"), SYSTEM_ERROR(500, "出现错误"), REQUIRE_USERNAME(504, "必须填写用户名"), LOGIN_ERROR(505, "用户名或密码错误"), CONTENT_NOT_NULL(506, "内容不能为空"), FILE_TYPE_ERROR(507, "文件格式错误,请上传正确格式的文件"), FILE_TOO_LARGE(413, "上传失败,文件过大"), USERNAME_NOT_NULL(508, "用户名不能为空"), NICKNAME_NOT_NULL(509, "昵称不能为空"), PASSWORD_NOT_NULL(510, "密码不能为空"), EMAIL_NOT_NULL(511, "邮箱不能为空"), USERNAME_EXIST(501, "用户名已存在"), PHONENUMBER_EXIST(502, "手机号已存在"), EMAIL_EXIST(503, "邮箱已存在"), NICKNAME_EXIST(512, "昵称已存在"); private final int code; private final String msg; AppHttpCodeEnum(int code, String errorMsg) { this.code = code; this.msg = errorMsg; } public int getCode() { return code; } public String getMsg() { return msg; }}
统一响应类
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121@JsonInclude(JsonInclude.Include.NON_NULL)public class ResponseResult
统一异常处理 与 自定义异常处理
需要在 handler处理包 下新建一个 GlobalExceptionHandler全局异常统一处理配置类,否侧出现异常前端不会直接提示500错误代码与错误信息
自定义异常
1234567891011121314151617181920212223242526272829303132333435363738/** * 自定义系统异常 */public class SystemException extends RuntimeException{ private int code; private String msg; public int getCode() { return code; } public String getMsg() { return msg; } public SystemException(AppHttpCodeEnum appHttpCodeEnum){ super(appHttpCodeEnum.getMsg()); this.code = appHttpCodeEnum.getCode(); this.msg = appHttpCodeEnum.getMsg(); } public SystemException(AppHttpCodeEnum appHttpCodeEnum, String msg){ super(msg); this.code = appHttpCodeEnum.getCode(); this.msg = msg; } public SystemException(int code, String msg){ super(msg); this.code = code; this.msg = msg; }}
全局异常统一处理配置类
12345678910111213141516171819202122232425262728293031323334353637/** * 全局异常统一处理配置类 * *///@ControllerAdvice//@ResponseBody@RestControllerAdvice // @ControllerAdvice+@ResponseBody 复合注解@Slf4j // 日志public class GlobalExceptionHandler { // 统一异常处理 // 自定义异常处理 @ExceptionHandler(SystemException.class) public ResponseResult systemExceptionHandler(SystemException e){ System.out.println("进入系统异常: "+e.toString()); // 打印异常信息 log.error("出现了异常! {}", e.toString(), e); // 从异常对象中获取信息封装result返回 ResponseResult result = ResponseResult.errorResult(e.getCode(), e.getMsg()); return result; } // 统一异常处理 @ExceptionHandler(Exception.class) public ResponseResult exceptionHandler(Exception e){ System.out.println("进入全局Exception异常: "+e.toString()); // 打印异常信息 log.error("出现了异常! {}", e.toString(), e); // 从异常对象中获取信息封装result返回 ResponseResult result = ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR, e.getMessage()); return result; }}
配置七牛云OSS服务
在 application.yml文件 中设置 上传凭证 与 仓库名(非必要),上传代码和工具类的代码实现参考下列的博客:
七牛云文件上传代码模板(Java)
redis配置
导入依赖后,在 application.yml文件 中配置 redis地址与端口信息,工具类代码实现如下:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217@SuppressWarnings(value = { "unchecked", "rawtypes" })@Componentpublic class RedisCache { @Autowired public RedisTemplate redisTemplate; /** * 缓存基本的对象,Integer、String、实体类等 * * @param key 缓存的键值 * @param value 缓存的值 */ public
配置日志记录
使用AOP实现日志记录,参考下面博客:
SpringBoot使用AOP实现日志记录 + Slf4j 日志配置
配置热部署与使用方法
参考以下转载博客:
IDEA 2021.2版本 DevTools 热部署配置无效的解决方案
Spring Boot 整合 DevTools(实现热部署)
使用Spring Boot Devtools实现热部署
Swagger2配置
启用Swagger2
1234567891011121314151617181920@SpringBootApplication@MapperScan("org.bailang.mapper")@Slf4j@EnableScheduling // 开启定时任务@EnableSwagger2 // 开启 Swagger2public class BaiLangBlogApplication { public static void main(String[] args) { SpringApplication.run(BaiLangBlogApplication.class, args); System.out.println("\n" + "____ __ ____ __ __ __ .___________. ___________ __ ____ ___ ____ ____ _______ _______.\n" + "\\ \\ / \\ / / | | | | | | | || ____\\ \\ / \\ / / / \\ \\ \\ / / | ____| / |\n" + " \\ \\/ \\/ / | |__| | | | `---| |----`| |__ \\ \\/ \\/ / / ^ \\ \\ \\/ / | |__ | (----`\n" + " \\ / | __ | | | | | | __| \\ / / /_\\ \\ \\ / | __| \\ \\ \n" + " \\ /\\ / | | | | | | | | | |____ \\ /\\ / / _____ \\ \\ / | |____.----) | \n" + " \\__/ \\__/ |__| |__| |__| |__| |_______| \\__/ \\__/ /__/ \\__\\ \\__/ |_______|_______/ \n" + " \n"); }}// 测试查看文档:访问 http://localhost:7777/swagger-ui.html 注意其中localhost和7777要调整成实际项目的域名和端口号
Controller配置、接口配置、接口参数配置 示例代码
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465@RestController@RequestMapping("/comment")@Api(tags = "评论", description = "评论相关接口-CommentController")public class CommentController { @Autowired private CommentService commentService; public static CommentService commentService_static; @PostConstruct public void init(){ commentService_static = commentService; } @GetMapping("/commentList") @SystemLog(BusinessName = "查询文章评论列表") @ApiOperation(value = "文章评论列表", notes = "获取一页文章评论") @ApiImplicitParams( { @ApiImplicitParam(name = "articleId", value = "文章ID", dataType = "long"), @ApiImplicitParam(name = "pageNum", value = "页号", dataType = "int"), @ApiImplicitParam(name = "pageSize", value = "每页大小", dataType = "int") } ) public ResponseResult commentList(Long articleId, Integer pageNum, Integer pageSize){ // 查询文章评论列表 ResponseResult result = commentService.commentList(SystemConstants.ARTICLE_COMMENT, articleId, pageNum, pageSize); return result; } @PostMapping @SystemLog(BusinessName = "发表评论") @ApiOperation(value = "发表评论", notes = "用户发表评论") @ApiImplicitParams( { @ApiImplicitParam(name = "addCommentDto", value = "新增评论 Dto对象", dataType = "AddCommentDto") } ) public ResponseResult addComment(@RequestBody AddCommentDto addCommentDto){ // 发表评论 // 将 dto 转为 数据库映射实体类 Comment comment = BeanCopyUtils.copyBean(addCommentDto, Comment.class); ResponseResult result = commentService.addComment(comment); return result; } @GetMapping("/linkCommentList") @SystemLog(BusinessName = "查询友联评论列表") @ApiOperation(value = "友联评论列表", notes = "获取一页友联评论") @ApiImplicitParams( { @ApiImplicitParam(name = "pageNum", value = "页号", dataType = "int"), @ApiImplicitParam(name = "pageSize", value = "每页大小", dataType = "int") } ) public ResponseResult linkCommentList(Integer pageNum, Integer pageSize){ // 查询友联评论列表 ResponseResult result = commentService.commentList(SystemConstants.LINK_COMMENT, null, pageNum, pageSize); return result; }}
实体类配置、实体类属性配置 示例代码
1234567891011121314151617181920212223242526272829303132333435363738394041/** * 新增评论接口 数据传输对象 */@Data@AllArgsConstructor@NoArgsConstructor@ApiModel(description = "新增评论DTO")public class AddCommentDto { // 标识主键ID @ApiModelProperty(notes = "标识主键ID") private Long id; //评论类型(0代表文章评论,1代表友链评论) @ApiModelProperty(notes = "评论类型(0代表文章评论,1代表友链评论)") private String type; //文章id @ApiModelProperty(notes = "文章id") private Long articleId; //根评论id @ApiModelProperty(notes = "根评论id") private Long rootId; //评论内容 @ApiModelProperty(notes = "评论内容") private String content; //所回复的目标评论的userid @ApiModelProperty(notes = "所回复的目标评论的userid") private Long toCommentUserId; //回复目标评论id @ApiModelProperty(notes = "回复目标评论id") private Long toCommentId; private Long createBy; private Date createTime; private Long updateBy; private Date updateTime; //逻辑删除标志(0代表未删除,1代表已删除) @ApiModelProperty(notes = "逻辑删除标志(0代表未删除,1代表已删除)") private Integer delFlag;}
文档信息配置
1234567891011121314151617181920212223242526/** * Swagger2文档信息配置 */@Configurationpublic class SwaggerConfig { @Bean public Docket customDocket(){ // 自定义 Docket return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("org.bailang.controller")) .build(); } private ApiInfo apiInfo(){ // 自定义 ApiInfo // Contact contact = new Contact("名字", "网站url地址", "邮箱"); // 联系方式 Contact contact = new Contact("WhiteWaves", "https://heyzqf.com", "WhiteWaves@qq.com"); return new ApiInfoBuilder() .title("测试 Swagger2 文档") // 文档标题 .description("这是一个测试Swagger2的文档") // 文档描述 .contact(contact) // 联系方式 .version("1.0.0") // 版本 .build(); }}
swagger2 注解说明
参考以下转载博客:
swagger2 注解说明
Web工具类
123456789101112131415161718192021222324252627282930313233343536373839404142public class WebUtils { /** * 将字符串渲染到客户端 * * @param response 渲染对象 * @param string 待渲染的字符串 * @return null */ public static void renderString(HttpServletResponse response, String string) { try { response.setStatus(200); // 设置 HTTP 的状态码, 说明HTTP请求成功 response.setContentType("application/json"); // 相应格式 json格式 response.setCharacterEncoding("utf-8"); response.getWriter().print(string); } catch (IOException e) { e.printStackTrace(); } } public static void setDownLoadHeader(String fileName, ServletContext context, HttpServletResponse response) throws UnsupportedEncodingException { } /** * 设置 下载Excel文件响应体信息 * * @param fileName 文件名 * @param response 响应体信息 * @throws UnsupportedEncodingException */ public static void setExcelDownLoadHeader(String fileName, HttpServletResponse response) throws UnsupportedEncodingException { // 设置ContentType响应头信息 response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); // 设置编码格式 response.setCharacterEncoding("utf-8"); // 对文件名进行转码 String fName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20"); // 设置Content-disposition响应头信息,filename下载文件名 response.setHeader("Content-disposition","attachment; filename="+fName); }}
Jwt工具类
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192/** * JWT工具类 */public class JwtUtil { //有效期为 public static final Long JWT_TTL = 24*60 * 60 *1000L;// 60 * 60 *1000 一个小时 //设置秘钥明文 public static final String JWT_KEY = "bailang"; public static String getUUID(){ String token = UUID.randomUUID().toString().replaceAll("-", ""); return token; } /** * 生成jwt * @param subject token中要存放的数据(json格式) * @return */ public static String createJWT(String subject) { JwtBuilder builder = getJwtBuilder(subject, null, getUUID());// 设置过期时间 return builder.compact(); } /** * 生成jwt * @param subject token中要存放的数据(json格式) * @param ttlMillis token超时时间 * @return */ public static String createJWT(String subject, Long ttlMillis) { JwtBuilder builder = getJwtBuilder(subject, ttlMillis, getUUID());// 设置过期时间 return builder.compact(); } private static JwtBuilder getJwtBuilder(String subject, Long ttlMillis, String uuid) { SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; SecretKey secretKey = generalKey(); long nowMillis = System.currentTimeMillis(); Date now = new Date(nowMillis); if(ttlMillis==null){ ttlMillis=JwtUtil.JWT_TTL; } long expMillis = nowMillis + ttlMillis; Date expDate = new Date(expMillis); return Jwts.builder() .setId(uuid) //唯一的ID .setSubject(subject) // 主题 可以是JSON数据 .setIssuer("bl") // 签发者 .setIssuedAt(now) // 签发时间 .signWith(signatureAlgorithm, secretKey) //使用HS256对称加密算法签名, 第二个参数为秘钥 .setExpiration(expDate); } /** * 创建token * @param id * @param subject * @param ttlMillis * @return */ public static String createJWT(String id, String subject, Long ttlMillis) { JwtBuilder builder = getJwtBuilder(subject, ttlMillis, id);// 设置过期时间 return builder.compact(); } /** * 生成加密后的秘钥 secretKey * @return */ public static SecretKey generalKey() { byte[] encodedKey = Base64.getDecoder().decode(JwtUtil.JWT_KEY); SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES"); return key; } /** * 解析 * * @param jwt * @return * @throws Exception */ public static Claims parseJWT(String jwt) throws Exception { SecretKey secretKey = generalKey(); return Jwts.parser() .setSigningKey(secretKey) .parseClaimsJws(jwt) .getBody(); }}
Bean拷贝工具类
1234567891011121314151617181920212223242526272829303132/** * Bean拷贝工具类 */public class BeanCopyUtils { private BeanCopyUtils() { } // 拷贝单个对象 public static
Security工具类
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455public class SecurityUtils { /** * 判断是否管理员 * Id为 1 的用户为管理员 */ public static Boolean isAdmin(){ Long userId = getUserID(); return userId!=null && userId==1L; } /** * 存入 用户信息 */ public static void setAuthentication(LoginUser loginUser){ // 用户信息存入 SecurityContextHolder UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, null); getContext().setAuthentication(authenticationToken); return ; } /** * 获取 用户ID * @return User ID */ public static Long getUserID(){ return getLoginUser().getUser().getId(); } /** * 获取 用户信息 * @return LoginUser */ public static LoginUser getLoginUser(){ return (LoginUser) getAuthentication().getPrincipal(); } /** * 获取 Authentication * */ public static Authentication getAuthentication(){ return getContext().getAuthentication(); } /** * 获取 SecurityContext * */ public static SecurityContext getContext(){ return SecurityContextHolder.getContext(); }}
参考链接
一个完整的springboot项目所需要导入的依赖合集(方便查找)
SpringBoot的pom.xml之依赖版本管理
Spring Boot项目中pom.xml文件各标签详解
spring boot 配置文件pom.xml详解
超级详细的Maven教程(四)Maven核心配置文件:pom.xml详解
IDEA 2021.2版本 DevTools 热部署配置无效的解决方案
Spring Boot 整合 DevTools(实现热部署)
使用Spring Boot Devtools实现热部署