通过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;
}
}
@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;
}
}
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;
}
}
<?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>
# 日志文件配置路径
logging:
config: classpath:log4j2-dev.xml
在多模块(微服务项目中一般放在base项目中)
微服务项目搭建解析
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;
}
}
/**
* 错误响应参数包装
*/
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;
}
}
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());
}
}
@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());
}
}
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"
}
}
### 课程查询接口
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
JSR (Java Specification Requests) 是一套 JavaBean 参数校验的标准
通过Java提供的注解,来达到参数校验效果
- @NotEmpty(message = “修改课程名称不能为空”,groups={ValidationGroups.Update.class})
- @NotEmpty(message = “适用人群不能为空”)
- @Size(message = “适用人群内容过少”,min = 10)
public class ValidationGroups {
//用于添加校验
public interface Inster{};
//用于修改校验
public interface Update{};
public interface Delete{};
}
insert分组为例
@PostMapping("/course")
public CourseBaseInfoDto createCourseBase(@RequestBody @Validated(ValidationGroups.Inster.class) AddCourseDto addCourseDto){
Long companyId = 22L;
return courseBaseInfoService.createCourseBase(companyId,addCourseDto);
}
@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;
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="">
mapper>
<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>
①鼠标控制代码大小
settins - editor - general - MouseControl(change font size...)
②file tepmlate
settings - file and code templates - Files(添加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} {
}
③隐藏文件设置
勾选上disable new inspections by default,否则会每次重启idea都会恢复默认设置
设置之后,在实现了Serializable的类上,通过alt+enter即可自动生成UID
@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());
};
}
}