之前也一直很少有写SpringBoot项目相关的文章,今天 准备整理一个我自己初始化SpringBoot项目时的一个脚手架,便于自己后面查阅。因为SpringBoot的约定大于配置,在整合各个组件的时候,我们仅仅写很少的代码就能 整合 跑起来。

本文,也仅仅是一个简单的整合,更多个性化配置,更多调优,这个也是自己在工作中慢慢摸索的。如果你有什么更多好的建议或者意见,也可以留言交流。谢谢~

我们开始吧

新建SpringBoot 2.0.3.RELEASE web 项目

意图:可以看到,每个对于每个请求,开始与结束一目了然,并且打印了以下参数:

  1. URL: 请求接口地址;
  2. HTTP Method: 请求的方法,是 POST, GET, 还是 DELETE 等;
  3. Class Method: 对应 Controller 的全路径以及调用的哪个方法;
  4. IP: 请求 IP 地址;
  5. Request Args: 请求入参,以 JSON 格式输出;
  6. Response Args: 响应出参,以 JSON 格式输出;
  7. Time-Consuming: 请求耗时;

在这里插入图片描述
步骤一:添加依赖:

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-aop</artifactId>
  4. </dependency>
  5. <!-- 用于日志切面中,以 json 格式打印出入参 -->
  6. <dependency>
  7. <groupId>com.google.code.gson</groupId>
  8. <artifactId>gson</artifactId>
  9. <version>2.8.5</version>
  10. </dependency>
  11. <!-- lombok -->
  12. <dependency>
  13. <groupId>org.projectlombok</groupId>
  14. <artifactId>lombok</artifactId>
  15. <optional>true</optional>
  16. </dependency>

步骤二:新建一个包aspect
自定义一个注解:

  1. import java.lang.annotation.*;
  2. /**
  3. * Description: TODO
  4. *
  5. * @Author: 留歌36
  6. * @Date: 2019-11-27 15:43
  7. */
  8. @Retention(RetentionPolicy.RUNTIME)
  9. @Target({ElementType.METHOD})
  10. @Documented
  11. public @interface WebLog {
  12. /** 日志描述信息 */
  13. String description() default "";
  14. }

新建注解类:

  1. import com.google.gson.Gson;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.aspectj.lang.JoinPoint;
  4. import org.aspectj.lang.ProceedingJoinPoint;
  5. import org.aspectj.lang.annotation.*;
  6. import org.springframework.stereotype.Component;
  7. import org.springframework.web.context.request.RequestContextHolder;
  8. import org.springframework.web.context.request.ServletRequestAttributes;
  9. import javax.servlet.http.HttpServletRequest;
  10. import java.lang.reflect.Method;
  11. /**
  12. * Description: 查看 https://www.cnblogs.com/quanxiaoha/p/10414681.html
  13. *
  14. * @Author: 留歌36
  15. * @Date: 2019-11-08 11:00
  16. */
  17. @Aspect
  18. @Component
  19. @Slf4j
  20. public class WebLogAspect {
  21. /** 换行符 */
  22. private static final String LINE_SEPARATOR = System.lineSeparator();
  23. /** 以自定义 @WebLog 注解为切点 */
  24. @Pointcut("@annotation(com.csylh.boot2all.aspect.WebLog)")
  25. public void webLog() {}
  26. /**
  27. * 在切点之前织入
  28. * @param joinPoint
  29. * @throws Throwable
  30. */
  31. @Before("webLog()")
  32. public void doBefore(JoinPoint joinPoint) throws Throwable {
  33. // 开始打印请求日志
  34. ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
  35. HttpServletRequest request = attributes.getRequest();
  36. // 获取 @WebLog 注解的描述信息
  37. String methodDescription = getAspectLogDescription(joinPoint);
  38. // 打印请求相关参数
  39. log.info("========================================== Start ==========================================");
  40. // 打印请求 url
  41. log.info("URL : {}", request.getRequestURL().toString());
  42. // 打印描述信息
  43. log.info("Description : {}", methodDescription);
  44. // 打印 Http method
  45. log.info("HTTP Method : {}", request.getMethod());
  46. // 打印调用 controller 的全路径以及执行方法
  47. log.info("Class Method : {}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
  48. // 打印请求的 IP
  49. log.info("IP : {}", request.getRemoteAddr());
  50. // 打印请求入参
  51. log.info("Request Args : {}", new Gson().toJson(joinPoint.getArgs()));
  52. }
  53. /**
  54. * 在切点之后织入
  55. * @throws Throwable
  56. */
  57. @After("webLog()")
  58. public void doAfter() throws Throwable {
  59. // 接口结束后换行,方便分割查看
  60. log.info("=========================================== End ===========================================" + LINE_SEPARATOR);
  61. }
  62. /**
  63. * 环绕
  64. * @param proceedingJoinPoint
  65. * @return
  66. * @throws Throwable
  67. */
  68. @Around("webLog()")
  69. public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
  70. long startTime = System.currentTimeMillis();
  71. Object result = proceedingJoinPoint.proceed();
  72. // 打印出参
  73. log.info("Response Args : {}", new Gson().toJson(result));
  74. // 执行耗时
  75. log.info("Time-Consuming : {} ms", System.currentTimeMillis() - startTime);
  76. return result;
  77. }
  78. /**
  79. * 获取切面注解的描述
  80. *
  81. * @param joinPoint 切点
  82. * @return 描述信息
  83. * @throws Exception
  84. */
  85. public String getAspectLogDescription(JoinPoint joinPoint)
  86. throws Exception {
  87. String targetName = joinPoint.getTarget().getClass().getName();
  88. String methodName = joinPoint.getSignature().getName();
  89. Object[] arguments = joinPoint.getArgs();
  90. Class targetClass = Class.forName(targetName);
  91. Method[] methods = targetClass.getMethods();
  92. StringBuilder description = new StringBuilder("");
  93. for (Method method : methods) {
  94. if (method.getName().equals(methodName)) {
  95. Class[] clazzs = method.getParameterTypes();
  96. if (clazzs.length == arguments.length) {
  97. description.append(method.getAnnotation(WebLog.class).description());
  98. break;
  99. }
  100. }
  101. }
  102. return description.toString();
  103. }
  104. }

就这样就OK。测试:

在这里插入图片描述

在这里插入图片描述
意图:生成文档形式的API并提供给不同的团队使用

便于自己单测

无需过多冗余的word文档,这一点很重要,因为我在工作中就遇到这么一个情况,由于开发使用的文档和最新文档版本导致不一致,导致后期很烦人

步骤一:添加依赖

  1. <dependency>
  2. <groupId>io.springfox</groupId>
  3. <artifactId>springfox-swagger2</artifactId>
  4. <version>2.4.0</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>io.springfox</groupId>
  8. <artifactId>springfox-swagger-ui</artifactId>
  9. <version>2.4.0</version>
  10. </dependency>

步骤2:新建swagger2配置类

  1. import org.springframework.context.annotation.Bean;
  2. import org.springframework.context.annotation.Configuration;
  3. import springfox.documentation.builders.ApiInfoBuilder;
  4. import springfox.documentation.builders.ParameterBuilder;
  5. import springfox.documentation.builders.PathSelectors;
  6. import springfox.documentation.builders.RequestHandlerSelectors;
  7. import springfox.documentation.schema.ModelRef;
  8. import springfox.documentation.service.ApiInfo;
  9. import springfox.documentation.service.Contact;
  10. import springfox.documentation.service.Parameter;
  11. import springfox.documentation.spi.DocumentationType;
  12. import springfox.documentation.spring.web.plugins.Docket;
  13. import springfox.documentation.swagger2.annotations.EnableSwagger2;
  14. import java.util.ArrayList;
  15. import java.util.List;
  16. /**
  17. * Description:
  18. *
  19. * @author: 留歌36
  20. * Date:2018/9/14 16:29
  21. */
  22. @Configuration
  23. @EnableSwagger2
  24. public class Swagger2 {
  25. /**
  26. * @Description:swagger2的配置文件,这里可以配置swagger2的一些基本的内容,比如扫描的包等等
  27. */
  28. @Bean
  29. public Docket createRestApi() {
  30. // 为swagger添加header参数可供输入
  31. // ParameterBuilder userTokenHeader = new ParameterBuilder();
  32. // ParameterBuilder userIdHeader = new ParameterBuilder();
  33. // List<Parameter> pars = new ArrayList<Parameter>();
  34. // userTokenHeader.name("headerUserToken").description("userToken")
  35. // .modelRef(new ModelRef("string")).parameterType("header")
  36. // .required(false).build();
  37. // userIdHeader.name("headerUserId").description("userId")
  38. // .modelRef(new ModelRef("string")).parameterType("header")
  39. // .required(false).build();
  40. // pars.add(userTokenHeader.build());
  41. // pars.add(userIdHeader.build());
  42. return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()
  43. // 注意修改这里 .apis(RequestHandlerSelectors.basePackage("com.zd.tongnan.controller"))
  44. .paths(PathSelectors.any()).build()
  45. .globalOperationParameters(setHeaderToken());
  46. // .globalOperationParameters(pars);
  47. }
  48. private List<Parameter> setHeaderToken() {
  49. ParameterBuilder tokenPar = new ParameterBuilder();
  50. List<Parameter> pars = new ArrayList<>();
  51. tokenPar.name("token").description("token").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
  52. pars.add(tokenPar.build());
  53. return pars;
  54. }
  55. /**
  56. * @Description: 构建 api文档的信息
  57. */
  58. private ApiInfo apiInfo() {
  59. return new ApiInfoBuilder()
  60. // 设置页面标题
  61. .title("xxx系统-接口数据文档")
  62. // 描述
  63. .description("xxx接口数据文档")
  64. // 设置联系人
  65. .contact(new Contact("留歌36","https://blog.csdn.net/liuge36",""))
  66. // .contact(new Contact("留歌36", "http://csylh.cn", "csylh36@163.com"))
  67. // 定义版本号
  68. .version("V-1.0.0").build();
  69. }
  70. }

步骤三:使用注解 ,主要是配置 在 controller类名,controller方法 和 实体类这三个地方
demo:

controller 类名上

  1. @Api(value = “用户注册登录接口”,tags = {“登录注册注销的controller”})
  2. public class UserController{}

controller类 方法名上

  1. @ApiOperation:用在请求的方法上,说明方法的用途、作用
  2. - value=“说明方法的用途、作用”
  3. - notes=“方法的备注说明”
  4. 案例:
  5. @ApiOperation(value = “用户注册接口”, notes=“这是用户注册的接口,随便写都可以”)
  6. public ServerResponse register(@RequestBody Users user){
  7. return iUserService.register(user);
  8. }

controller 类方法参数上

1.@RequestParam ⇒ @ApiImplicitParams
使用@ApiImplicitParams来定义参数

  1. @ApiImplicitParams({
  2. @ApiImplicitParam(name="name",value="内存名",dataType="string", paramType = "query"),
  3. })

2.@RequestBody ⇒ @ApiModelProperty(value = “用户名”,name = “username”,example = “admin”,required = true) :注:这里是在对应的实体类上的各个属性上添加注解

区别:一个是在实体类上添加注解@ApiModelProperty
一个是在方法 参数上面添加注解@ApiImplicitParams

更多使用,参考 这里

在这里插入图片描述
意图:这个是常用的持久层框架,虽然spring-data-jpa也是很优秀的。但是我自己在工作中这个用的比较多一点。

SpringBoot 整合 Mybatis 有两种常用的方式,一种就是我们常见的 xml 的方式 ,还有一种是全注解的方式。

如何选择:在 SQL 语句不太长的情况下,我觉得全注解的方式一定是比较清晰简洁的。但是,复杂的 SQL 确实不太适合和代码写在一起,那么就使用xml文件的形式。其实这两个方法也没差。

步骤1:添加依赖

  1. <dependency>
  2. <groupId>mysql</groupId>
  3. <artifactId>mysql-connector-java</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.mybatis.spring.boot</groupId>
  7. <artifactId>mybatis-spring-boot-starter</artifactId>
  8. <version>1.3.1</version>
  9. </dependency>

步骤2:配置 application.properties

  1. server.port=9099
  2. # 暂时使用SpringBoot2 自带的 HikariCP 连接池,后面结合Druid
  3. spring.datasource.url=jdbc:mysql://192.168.1.200:3306/test2?useUnicode=true&characterEncoding=UTF-8&useSSL=false
  4. spring.datasource.username=db
  5. spring.datasource.password=xxx
  6. spring.datasource.driver-class-name=com.mysql.jdbc.Driver
  7. #Mybatis 配置
  8. mybatis.config-location=classpath:mybatis-config.xml
  9. mybatis.mapper-locations=classpath*:/mappers/**.xml
  10. mybatis.type-aliases-package=com.liuge36.emr.entity

步骤3:resources 下新建mybatis-config.xml ,并建立自己的entity包

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE configuration
  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <configuration>
  6. <!-- 配置全局属性 -->
  7. <settings>
  8. <!-- 使用jdbc的getGeneratedKeys获取数据库自增主键值 -->
  9. <setting name="useGeneratedKeys" value="true" />
  10. <!-- 使用列标签替换列别名 默认:true -->
  11. <setting name="useColumnLabel" value="true" />
  12. <!-- 开启驼峰命名转换:Table{create_time} -> Entity{createTime} -->
  13. <setting name="mapUnderscoreToCamelCase" value="true" />
  14. </settings>
  15. </configuration>

步骤4:测试
新建dao包,新建MemoryDao接口

  1. import cn.com.zdmedical.emr.entity.Memory;
  2. import org.apache.ibatis.annotations.Mapper;
  3. import org.apache.ibatis.annotations.Param;
  4. /**
  5. * Description: TODO
  6. *
  7. * @Author: 留歌36
  8. * @Date: 2019-11-28 09:10
  9. */
  10. @Mapper
  11. public interface MemoryDao {
  12. /** 根据名字查找内存信息 */
  13. Memory findMemoryByName(@Param("name") String name);
  14. }

xml 实现:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  3. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  4. <mapper namespace="com.liuge36.emr.dao.MemoryDao">
  5. <select id="findMemoryByName" parameterType="String" resultType="com.liuge36.emr.entity.Memory">
  6. SELECT * FROM memory WHERE name = #{name}
  7. </select>
  8. </mapper>

其余的就是基本的常规业务操作了。
注解的方式:

  1. @Mapper
  2. public interface UserDao {
  3. /**
  4. * 通过名字查询用户信息
  5. */
  6. @Select("SELECT * FROM user WHERE name = #{name}")
  7. User findUserByName(@Param("name") String name);
  8. /**
  9. * 查询所有用户信息
  10. */
  11. @Select("SELECT * FROM user")
  12. List<User> findAllUser();
  13. /**
  14. * 插入用户信息
  15. */
  16. @Insert("INSERT INTO user(name, age,money) VALUES(#{name}, #{age}, #{money})")
  17. void insertUser(@Param("name") String name, @Param("age") Integer age, @Param("money") Double money);
  18. /**
  19. * 根据 id 更新用户信息
  20. */
  21. @Update("UPDATE user SET name = #{name},age = #{age},money= #{money} WHERE id = #{id}")
  22. void updateUser(@Param("name") String name, @Param("age") Integer age, @Param("money") Double money,
  23. @Param("id") int id);
  24. /**
  25. * 根据 id 删除用户信息
  26. */
  27. @Delete("DELETE from user WHERE id = #{id}")
  28. void deleteUser(@Param("id") int id);
  29. }

所以,其实SpringBoot整合这些框架的 基本 使用还是很简单的。

在这里插入图片描述
https://github.com/alibaba/druid

阿里巴巴数据库事业部出品,为监控而生的数据库连接池

Druid是Java语言中最好的数据库连接池。Druid能够提供强大的监控和扩展功能。

步骤1:添加依赖

  1. <dependency>
  2. <groupId>com.alibaba</groupId>
  3. <artifactId>druid-spring-boot-starter</artifactId>
  4. <version>1.1.10</version>
  5. </dependency>

步骤2:配置 application.properties

  1. #spring.datasource.url=jdbc:mysql://192.168.1.200:3306/test2?useUnicode=true&characterEncoding=UTF-8&useSSL=false
  2. #spring.datasource.username=root
  3. #spring.datasource.password=xx
  4. #spring.datasource.driver-class-name=com.mysql.jdbc.Driver
  5. # 这4个参数key里不带druid也可以,即可以还用上面的这个4个参数
  6. spring.datasource.druid.url=jdbc:mysql://192.168.1.200:3306/test2?useUnicode=true&characterEncoding=UTF-8&useSSL=false
  7. spring.datasource.druid.username=root
  8. spring.datasource.druid.password=xx
  9. spring.datasource.druid.driver-class-name=com.mysql.jdbc.Driver
  10. # 初始化时建立物理连接的个数
  11. spring.datasource.druid.initial-size=5
  12. # 最大连接池数量
  13. spring.datasource.druid.max-active=30
  14. # 最小连接池数量
  15. spring.datasource.druid.min-idle=5
  16. # 获取连接时最大等待时间,单位毫秒
  17. spring.datasource.druid.max-wait=60000
  18. # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
  19. spring.datasource.druid.time-between-eviction-runs-millis=60000
  20. # 连接保持空闲而不被驱逐的最小时间
  21. spring.datasource.druid.min-evictable-idle-time-millis=300000
  22. # 用来检测连接是否有效的sql,要求是一个查询语句
  23. spring.datasource.druid.validation-query=SELECT 1 FROM DUAL
  24. # 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
  25. spring.datasource.druid.test-while-idle=true
  26. # 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
  27. spring.datasource.druid.test-on-borrow=false
  28. # 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
  29. spring.datasource.druid.test-on-return=false
  30. # 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。
  31. spring.datasource.druid.pool-prepared-statements=true
  32. # 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。
  33. spring.datasource.druid.max-pool-prepared-statement-per-connection-size=50
  34. # 配置监控统计拦截的filters,去掉后监控界面sql无法统计
  35. spring.datasource.druid.filters=stat,wall
  36. # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
  37. spring.datasource.druid.connection-properties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
  38. # 合并多个DruidDataSource的监控数据
  39. spring.datasource.druid.use-global-data-source-stat=true

步骤3:访问 http://127.0.0.1:9099/druid/index.html
在这里插入图片描述
打开mysql客户端navicat的sql窗口,执行show full processlist,显示如下内容:
在这里插入图片描述
可以看到,启动项目后,直接创建5个数据连接,这是由application.properties配置文件中spring.datasource.druid.initial-size=5控制的。

在这里插入图片描述

步骤4:druid监控
在步骤3我们可以看到,浏览器输入http://127.0.0.1:9099/druid/index.html直接就能看到druid控制台界面,在这里面可以看到很多项目信息,如果任凭用户随意访问,非常危险。我们可以通过配置,设置只有通过登录认证才可以访问。

在application.properties配置文件中增加:

  1. # druid连接池监控
  2. spring.datasource.druid.stat-view-servlet.login-username=admin
  3. spring.datasource.druid.stat-view-servlet.login-password=admin
  4. # 排除一些静态资源,以提高效率
  5. spring.datasource.druid.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*

再次访问:http://127.0.0.1:9099/druid/login.html
在这里插入图片描述
输入 admin /admin 进去

4个常用JSON类库分别为:Gson,FastJson,Jackson,Json-lib

步骤1:添加依赖

  1. <dependency>
  2. <groupId>org.codehaus.jackson</groupId>
  3. <artifactId>jackson-mapper-asl</artifactId>
  4. <version>1.9.13</version>
  5. </dependency>

步骤2:修改配置文件

  1. # 属性为 空(””) 或者为 NULL 都不序列化
  2. spring.jackson.default-property-inclusion=non_empty

步骤3:新建 common 包
在包下新建:ResponseCode

  1. /**
  2. * Description:
  3. *
  4. * @author: 留歌36
  5. * Date:2018/11/4 16:04
  6. */
  7. public enum ResponseCode {
  8. SUCCESS(200,"成功"),
  9. ERROR(1,"错误"),
  10. NEED_REGISTER(10,"需要注册,请授权登录!"),
  11. NEED_LOGIN(12,"需要登录,请登录!"),
  12. TOMANYLOGIN(11,"账号被挤出."),
  13. ILLEGAL_ARGUMENT(2,"ILLEGAL_ARGUMENT");
  14. private final int code;
  15. private final String desc;
  16. ResponseCode(int code, String desc){
  17. this.code=code;
  18. this.desc=desc;
  19. }
  20. public int getCode(){
  21. return code;
  22. }
  23. public String getDesc(){
  24. return desc;
  25. }
  26. }

新建通用返回对象:

  1. import org.codehaus.jackson.annotate.JsonIgnore;
  2. import org.codehaus.jackson.map.annotate.JsonSerialize;
  3. import java.io.Serializable;
  4. /**
  5. * Description:
  6. *
  7. * @author: 留歌36
  8. * Date:2018/11/4 16:03
  9. */
  10. @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
  11. //保证序列化json的时候,如果是null的对象,key也会消失
  12. public class ServerResponse<T> implements Serializable{
  13. private int status;
  14. private String msg;
  15. private T data;//可以指定泛型里面的内容,也可以不指定,而且里面的类型可以是多种,map,list,string
  16. //编写外部访问的Public方法,之前需要写一个枚举类
  17. //这样外部的显示的就是这几个值啦
  18. public int getStatus(){
  19. return status;
  20. }
  21. public String getMsg(){
  22. return msg;
  23. }
  24. public T getData(){
  25. return data;
  26. }
  27. //判断是否登陆成功
  28. @JsonIgnore
  29. public boolean isSuccess(){
  30. return this.status == ResponseCode.SUCCESS.getCode();
  31. }
  32. //编写 私有 的构造方法,外部是不能new的
  33. // 开放供外部使用的Public方法
  34. private ServerResponse(int status){
  35. this.status=status;
  36. }
  37. private ServerResponse(int status, T data){
  38. this.status=status;
  39. this.data=data;
  40. }
  41. private ServerResponse(int status, String msg){
  42. this.status=status;
  43. this.msg=msg;
  44. }
  45. private ServerResponse(int status, String msg, T data){
  46. this.status=status;
  47. this.msg=msg;
  48. this.data=data;
  49. }
  50. //编写成功静态的方法供外部的调用
  51. public static <T> ServerResponse<T> createBySuccess(){
  52. return new ServerResponse<T>(ResponseCode.SUCCESS.getCode());
  53. }
  54. public static <T> ServerResponse<T> createBySuccess(T data){
  55. return new ServerResponse<T>(ResponseCode.SUCCESS.getCode(),data);
  56. }
  57. public static <T> ServerResponse<T> createBySuccess(String msg,T data){
  58. return new ServerResponse<T>(ResponseCode.SUCCESS.getCode(),msg,data);
  59. }
  60. public static <T> ServerResponse<T> createBySuccessMessage(String msg){
  61. return new ServerResponse<T>(ResponseCode.SUCCESS.getCode(),msg);
  62. }
  63. //编写失败的方法
  64. public static <T> ServerResponse<T> createByError(){
  65. return new ServerResponse<T>(ResponseCode.ERROR.getCode(),ResponseCode.ERROR.getDesc());
  66. }
  67. public static <T> ServerResponse<T> createByErrorMessage(String errorMessage) {
  68. return new ServerResponse<T>(ResponseCode.ERROR.getCode(),errorMessage);
  69. }
  70. public static <T> ServerResponse<T> createByErrorCodeMessage(int errorcode,String erroeMessage){
  71. return new ServerResponse<T>(errorcode,erroeMessage);
  72. }
  73. public static <T> ServerResponse<T> createByErrorNeeDLogin(String erroeMessage){
  74. return new ServerResponse<T>(ResponseCode.NEED_REGISTER.getCode(),erroeMessage);
  75. }
  76. }

允许全局跨域:

  1. import org.springframework.context.annotation.Bean;
  2. import org.springframework.context.annotation.Configuration;
  3. import org.springframework.web.cors.CorsConfiguration;
  4. import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
  5. import org.springframework.web.filter.CorsFilter;
  6. /**
  7. * Description: 配置全局跨域
  8. *
  9. * @Author: 留歌36
  10. * @Date: 2019-11-28 11:45
  11. */
  12. @Configuration
  13. public class GlobalCorsConfig {
  14. private CorsConfiguration buildConfig() {
  15. CorsConfiguration corsConfiguration = new CorsConfiguration();
  16. corsConfiguration.addAllowedOrigin("*");
  17. corsConfiguration.addAllowedHeader("*");
  18. corsConfiguration.addAllowedMethod("*");
  19. corsConfiguration.setAllowCredentials(true);
  20. return corsConfiguration;
  21. }
  22. @Bean
  23. public CorsFilter corsFilter() {
  24. UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
  25. source.registerCorsConfiguration("/**", buildConfig());
  26. return new CorsFilter(source);
  27. }
  28. }

SQL样例:

  1. create database imooc_homepage_sc;
  2. -- 用户信息表
  3. create table if not exists `imooc_homepage_sc`.`homepage_user` (
  4. `id` bigint(20) not null auto_increment comment '自增ID',
  5. `username` varchar(128) not null default '' comment '用户名',
  6. `email` varchar(128) not null default '' comment '用户邮箱',
  7. `create_time` datetime not null default '1970-01-01 08:00:00' comment '创建时间',
  8. `update_time` datetime not null default '1970-01-01 08:00:00' comment '更新时间',
  9. primary key(`id`),
  10. unique key `key_username` (`username`)
  11. )engine=InnoDB auto_increment=1 default charset=utf8 row_format=compact comment='用户信息表'
  12. -- 用户课程表
  13. create table if not exists `imooc_homepage_sc`.`homepage_user_course` (
  14. `id` bigint(20) not null auto_increment comment '自增ID',
  15. `user_id` bigint(20) not null default 0 comment '用户 ID',
  16. `course_id` bigint(20) not null default 0 comment '课程 ID',
  17. `create_time` datetime not null default '1970-01-01 08:00:00' comment '创建时间',
  18. `update_time` datetime not null default '1970-01-01 08:00:00' comment '更新时间',
  19. primary key(`id`),
  20. unique key `key_user_course` (`user_id`, `course_id`)
  21. )engine=InnoDB auto_increment=1 default charset=utf8 row_format=compact comment='用户课程表'
  22. -- 课程表
  23. create table if not exists `imooc_homepage_sc`.`homepage_course` (
  24. `id` bigint(20) not null auto_increment comment '自增ID',
  25. `course_name` varchar(128) not null default '' comment '课程名称',
  26. `course_type` varchar(128) not null default '' comment '课程类型',
  27. `course_icon` varchar(128) not null default '' comment '课程图标',
  28. `course_intro` varchar(128) not null default '' comment '课程介绍',
  29. `create_time` datetime not null default '1970-01-01 08:00:00' comment '创建时间',
  30. `update_time` datetime not null default '1970-01-01 08:00:00' comment '更新时间',
  31. primary key(`id`),
  32. unique key `key_course_name` (`course_name`)
  33. )engine=InnoDB auto_increment=1 default charset=utf8 row_format=compact comment='课程表'

未完待续~

更多好文:https://blog.csdn.net/liuge36

版权声明:本文为liuge36原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/liuge36/p/11950446.html