SpringBoot开发规范部分通用模板+idea配置【项目通用-1】

SpringBoot开发规范通用模板

1 分页插件使用

通过MybatisPlus配置分页插件拦截器

@Configuration
@MapperScan("com.xuecheng.content.mapper") //拦截的mapper层
public class MybatisPlusConfig {


    //定义分页的拦截器
    @Bean
    public MybatisPlusInterceptor getMybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return mybatisPlusInterceptor;
    }

}

2 通用返回结果

2.1 带分页通用返回结果

  • PageResult:
@Data
@ToString
public class PageResult<T> {
    // 数据列表
    private List<T> items;

    //总记录数
    private long counts;

    //当前页码
    private long page;

    //每页记录数
    private long pageSize;

    public PageResult(List<T> items, long counts, long page, long pageSize) {
        this.items = items;
        this.counts = counts;
        this.page = page;
        this.pageSize = pageSize;
    }

}

2.2 分页请求参数

PageParams(分页请求参数):

@Data
@ToString
public class PageParams {

    //当前页码默认值
    public static final long DEFAULT_PAGE_CURRENT = 1L;
    //每页记录数默认值
    public static final long DEFAULT_PAGE_SIZE = 10L;

    @ApiModelProperty("当前页码")
    //当前页码
    private Long pageNo = DEFAULT_PAGE_CURRENT;

    @ApiModelProperty("每页记录数")
    //每页记录数默认值
    private Long pageSize = DEFAULT_PAGE_SIZE;

    public PageParams() {

    }

    public PageParams(long pageNo, long pageSize) {
        this.pageNo = pageNo;
        this.pageSize = pageSize;
    }
}

2.3 日志处理

  • 日志配置文件
    log4j2-dev.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorInterval="180" packages="">
    <properties>
        <property name="logdir">logs</property>
        <property name="PATTERN">%date{YYYY-MM-dd HH:mm:ss,SSS} %level [%thread][%file:%line] - %msg%n%throwable</property>
    </properties>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="${PATTERN}"/>
        </Console>

        <RollingFile name="ErrorAppender" fileName="${logdir}/error.log"
            filePattern="${logdir}/$${date:yyyy-MM-dd}/error.%d{yyyy-MM-dd-HH}.log" append="true">
            <PatternLayout pattern="${PATTERN}"/>
            <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true" />
            </Policies>
        </RollingFile>

        <RollingFile name="DebugAppender" fileName="${logdir}/info.log"
            filePattern="${logdir}/$${date:yyyy-MM-dd}/info.%d{yyyy-MM-dd-HH}.log" append="true">
            <PatternLayout pattern="${PATTERN}"/>
            <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true" />
            </Policies>
        </RollingFile>
        
        <!--异步appender-->
         <Async name="AsyncAppender" includeLocation="true">
            <AppenderRef ref="ErrorAppender"/>
            <AppenderRef ref="DebugAppender"/>
        </Async>
    </Appenders>
    
    <Loggers>
         <!--过滤掉spring和mybatis的一些无用的debug信息-->
        <logger name="org.springframework" level="INFO">
        </logger>
        <logger name="org.mybatis" level="INFO">
        </logger>
        <logger name="cn.zi.wanxinp2p.consumer.mapper" level="DEBUG">
        </logger>

        <logger name="springfox" level="INFO">
        </logger>
		<logger name="org.apache.http" level="INFO">
        </logger>
        <logger name="com.netflix.discovery" level="INFO">
        </logger>
        
        <logger name="RocketmqCommon"  level="INFO" >
		</logger>
		
		<logger name="RocketmqRemoting" level="INFO"  >
		</logger>
		
		<logger name="RocketmqClient" level="WARN">
		</logger>

        <logger name="org.dromara.hmily" level="WARN">
        </logger>

        <logger name="org.dromara.hmily.lottery" level="WARN">
        </logger>

        <logger name="org.dromara.hmily.bonuspoint" level="WARN">
        </logger>
		
        <!--OFF   0-->
        <!--FATAL   100-->
        <!--ERROR   200-->
        <!--WARN   300-->
        <!--INFO   400-->
        <!--DEBUG   500-->
        <!--TRACE   600-->
        <!--ALL   Integer.MAX_VALUE-->
        <Root level="DEBUG" includeLocation="true">
            <AppenderRef ref="AsyncAppender"/>
            <AppenderRef ref="Console"/>
            <AppenderRef ref="DebugAppender"/>
        </Root>
    </Loggers>
</Configuration>

  • application.yml配置:
# 日志文件配置路径
logging:
  config: classpath:log4j2-dev.xml

3 全局异常处理

在多模块(微服务项目中一般放在base项目中)
微服务项目搭建解析

3.1 通用异常

public enum CommonError {

	UNKOWN_ERROR("执行过程异常,请重试。"),
	PARAMS_ERROR("非法参数"),
	OBJECT_NULL("对象为空"),
	QUERY_NULL("查询结果为空"),
	REQUEST_NULL("请求参数为空");

	private String errMessage;

	public String getErrMessage() {
		return errMessage;
	}

	private CommonError( String errMessage) {
		this.errMessage = errMessage;
	}

}

3.2 错误响应参数包装

/**
 * 错误响应参数包装
 */
public class RestErrorResponse implements Serializable {

    private String errMessage;

    public RestErrorResponse(String errMessage){
        this.errMessage= errMessage;
    }

    public String getErrMessage() {
        return errMessage;
    }

    public void setErrMessage(String errMessage) {
        this.errMessage = errMessage;
    }
}

3.3 自定义异常

public class XueChengPlusException extends RuntimeException {

    private String errMessage;

    public XueChengPlusException() {
        super();
    }

    public XueChengPlusException(String message) {
        super(message);
        this.errMessage = message;
    }

    public String getErrMessage(){
        return errMessage;
    }

    public static void cast(String errMessage){
        throw new XueChengPlusException(errMessage);
    }
    public static void cast(CommonError commonError){
        throw new XueChengPlusException(commonError.getErrMessage());
    }
}

3.4 全局异常处理器

@Slf4j
 @ControllerAdvice//控制器增强
public class GlobalExceptionHandler {

  //处理XueChengPlusException异常  此类异常是程序员主动抛出的,可预知异常
  @ResponseBody//将信息返回为 json格式
  @ExceptionHandler(XueChengPlusException.class)//此方法捕获XueChengPlusException异常
  @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)//状态码返回500
  public RestErrorResponse doXueChengPlusException(XueChengPlusException e){

   log.error("捕获异常:{}",e.getErrMessage());
   e.printStackTrace();

   String errMessage = e.getErrMessage();

   return new RestErrorResponse(errMessage);
  }


  //捕获不可预知异常 Exception
  @ResponseBody//将信息返回为 json格式
  @ExceptionHandler(Exception.class)//此方法捕获Exception异常
  @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)//状态码返回500
  public RestErrorResponse doException(Exception e){

   log.error("捕获异常:{}",e.getMessage());
   e.printStackTrace();

   return new RestErrorResponse(CommonError.UNKOWN_ERROR.getErrMessage());
  }

    @ResponseBody//将信息返回为 json格式
    @ExceptionHandler(MethodArgumentNotValidException.class)//此方法捕获MethodArgumentNotValidException异常
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)//状态码返回500
    public RestErrorResponse doMethodArgumentNotValidException(MethodArgumentNotValidException e){

        BindingResult bindingResult = e.getBindingResult();
        //校验的错误信息
        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
        //收集错误
        StringBuffer errors = new StringBuffer();
        fieldErrors.forEach(error->{
            errors.append(error.getDefaultMessage()).append(",");
        });

        return new RestErrorResponse(errors.toString());
    }

}

4 HttpClient插件使用

  • 在idea插件中下载httpclient
  • 编写对应环境配置文件xxxx.json,例如:
{
  "dev": {
    "access_token": "",
    "gateway_host": "localhost:63010",
    "content_host": "localhost:63040",
    "system_host": "localhost:63110",
    "media_host": "localhost:63050",
    "search_host": "localhost:63080",
    "auth_host": "localhost:63070",
    "checkcode_host": "localhost:63075",
    "learning_host": "localhost:63020"
  }
}
  • 点击controller中的图标,自动生成文件或自己创建xxx.http
    在这里插入图片描述
### 课程查询接口
POST {{content_host}}/content/course/list?pageNo=1&pageSize=2
Content-Type: application/json

{
  "auditStatus": "202004",
  "courseName": "",
  "publishStatus": ""
}


### 课程分类 查询
GET {{content_host}}/content/course-category/tree-nodes




### 上传文件
POST {{media_host}}/media/upload/coursefile
Content-Type: multipart/form-data; boundary=WebAppBoundary

--WebAppBoundary
Content-Disposition: form-data; name="filedata"; filename="2.jpg"
Content-Type: application/octet-stream

< d:/2.jpg

5 JSR校验

5.1 概念

JSR (Java Specification Requests) 是一套 JavaBean 参数校验的标准
通过Java提供的注解,来达到参数校验效果

  • @NotEmpty(message = “修改课程名称不能为空”,groups={ValidationGroups.Update.class})
  • @NotEmpty(message = “适用人群不能为空”)
  • @Size(message = “适用人群内容过少”,min = 10)

5.2 校验分组

  • 定义分组:
public class ValidationGroups {

 //用于添加校验
 public interface Inster{};
 //用于修改校验
 public interface Update{};
 public interface Delete{};

}
  • controller中使用

insert分组为例

@PostMapping("/course")
    public CourseBaseInfoDto createCourseBase(@RequestBody @Validated(ValidationGroups.Inster.class) AddCourseDto addCourseDto){

        Long companyId = 22L;
        return courseBaseInfoService.createCourseBase(companyId,addCourseDto);
    }

5.3 实体类校验

@Data
@ToString
@ApiModel(value="AddCourseDto", description="新增课程基本信息")
public class AddCourseDto {


 @NotEmpty(message = "添加课程名称不能为空",groups={ValidationGroups.Inster.class})
 @NotEmpty(message = "修改课程名称不能为空",groups={ValidationGroups.Update.class})
 @ApiModelProperty(value = "课程名称", required = true)
 private String name;

 @NotEmpty(message = "适用人群不能为空")
 @Size(message = "适用人群内容过少",min = 10)
 @ApiModelProperty(value = "适用人群", required = true)
 private String users;

6 Idea通用配置

6.1 常用插件

  • lombok
  • HTTPClient
  • Git、GitHub、Gitee、GitToolBox
  • Lombok
  • SpringBoot Initializr and Assistant
  • Translation
  • MybatisX
  • GeneraterAllSetter
  • JPA Buddy
  • Alibaba Java Code Guidelines
  • Translation
  • Raindow Brackets
  • HighlightBracketPair
  • Maven helper
  • Database Tools and SQL
  • Alibaba Java Coding Guidelines(编码规范)
  • MyBatisCodeHelper(直接查看SQL)

6.2 文件模板

①mapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="">
    
    
</mapper>
②spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd">

</beans>

6.3 tips

①鼠标控制代码大小

settins - editor - general - MouseControl(change font size...)

②file tepmlate

settings - file and code templates - Files(添加class模板)

在这里插入图片描述
class:

#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
#parse("File Header.java")
/**
 * @description TODO
 * @author zhouYi
 * @date ${DATE} ${TIME}
 * @version 
 */
public class ${NAME} {
}

interface:

#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
#parse("File Header.java")

/**
 * @description TODO
 * @author ${USER}
 * @date ${DATE} ${TIME}
 * @version 
 */
public interface ${NAME} {
}

③隐藏文件设置

在这里插入图片描述
④自动删除无用导包
在这里插入图片描述
⑤开启自动生成UUID
在这里插入图片描述

勾选上disable new inspections by default,否则会每次重启idea都会恢复默认设置

以前idea版本设置位置:
在这里插入图片描述

设置之后,在实现了Serializable的类上,通过alt+enter即可自动生成UID

在这里插入图片描述

7 时间转换配置LocalDateTimeConfig

@Configuration
public class LocalDateTimeConfig {

    /*
     * 序列化内容
     *   LocalDateTime -> String
     * 服务端返回给客户端内容
     * */
    @Bean
    public LocalDateTimeSerializer localDateTimeSerializer() {
        return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }

    /*
     * 反序列化内容
     *   String -> LocalDateTime
     * 客户端传入服务端数据
     * */
    @Bean
    public LocalDateTimeDeserializer localDateTimeDeserializer() {
        return new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }


    // 配置
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return builder -> {
            builder.serializerByType(LocalDateTime.class, localDateTimeSerializer());
            builder.deserializerByType(LocalDateTime.class, localDateTimeDeserializer());
        };
    }

}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值