搭建SpringBoot多模块微服务项目脚手架 第三篇文章,在搭建本篇文章内容前,先查看
搭建SpringBoot多模块微服务项目脚手架一)
搭建SpringBoot多模块微服务项目脚手架二)
搭建基础环境。
第一篇文章
https://blog.csdn.net/m0_38039437/article/details/129408124
搭建SpringBoot多模块微服务框架
第二篇文章
https://blog.csdn.net/m0_38039437/article/details/129419467
封装《MybatisPlus》
封装《Swagger》
封装《自动生成代码工具》
第三篇文章
封装《接口返回统一信息模板》
封装《接口统一请求信息模板》
封装《统一异常信息模板》
封装《统一日志模板》
我们返回的数据使用Json格式,返回的内容包含两个部分固定内容和可变内容,根据这个需求介绍下设计一个返回数据的模板思路。
1.首先设计json数据格式结构,例如下面的结构包含
2.设计json结构实现思路,下面会用实例介绍
{"success": true,"code": 20000,"message": "成功","data": {"items": [{"id": "1","name": "刘德华","intro": "毕业于师范大学数学系,热爱教育事业,执教数学思维6年有余"}]}
}
在common
公共模块下common_utils
模块中封装返回数据json格式,因为它是一个公共的功能并且不依赖业务,封装好之后在每个项目中都能够使用。
封装返回统一信息类中需要使用lombok提供get和set方法,因此我们在common
模块中导入依赖。
org.projectlombok lombok
状态码是一个常量值,因此设计状态码使用枚举类和接口两种方式都可以,这里使用接口设计状态码
common_utils
模块的java文件夹下新建包名 com.bruce.commonutils
com.bruce.commonutils
包下新建ResultCode
接口设计状态码这里只列举了几个状态码,在开发过程中会根据业务定义很多个失败的状态码,通过不同的状态码确认是哪个业务模块抛出的问题。
package com.bruce.commonutils;/*** @author bruce* @create 2023/3/9 18:58*/
public interface ResultCode {//返回状态成功public static Integer SUCCESS = 200;//返回用户模块没有登录权限状态码public static Integer ERROR = 10000;//返回用户模块没有登录权限状态码public static Integer ERROR_USER_LOGIN = 10000;//返回用户模块没有注册异常状态码public static Integer ERROR_USER_REGISTER = 10001;//返回课程模块没有购买课程状态码public static Integer ERROR_COURSE_PAY = 20000;
}
在commonutils
包下新建R
类设计统一返回结果信息
package com.bruce.commonutils;/*** @author bruce* @create 2023/3/9 19:11*/import io.swagger.annotations.ApiModelProperty;
import lombok.Data;import java.util.HashMap;
import java.util.Map;//lombok为属性提供get和set方法
@Data
public class R {//将json格式中的字段定义为类属性//Swagger注解,如果没有集成Swagger可以不用,建议使用@ApiModelProperty(value = "是否成功")private Boolean success;@ApiModelProperty(value = "返回码")private Integer code;@ApiModelProperty(value = "返回消息")private String message;@ApiModelProperty(value = "返回数据")private Map data = new HashMap();//私有化构造器,使其他类只能调用提供的方法private R() {}//结果返回成功静态方法public static R ok(){R r = new R();r.setSuccess(true);r.setCode(ResultCode.SUCCESS);r.setMessage("成功");return r;}//结果返回失败静态方法public static R error(){R resultMessage = new R();resultMessage.setSuccess(false);resultMessage.setCode(ResultCode.ERROR);resultMessage.setMessage("失败");return resultMessage;}public R success(Boolean success){this.setSuccess(success);return this;}// 提供自定义信息的方法,由调用者传入public R message(String message){this.setMessage(message);return this;}public R code(Integer code){this.setCode(code);return this;}public R data(String key, Object value){this.data.put(key, value);return this;}public R data(Map map){this.setData(map);return this;}}
统一返回结果格式放在了公共的包中,业务模块使用该功能是跨模块调用,因此需要在业务模块中加上common_utils
模块依赖。
例如在service
模块的pom.xml
文件中导入common_utils
依赖
com.bruce common_utils 0.0.1-SNAPSHOT
前端请求接口时通常将数据封装到JSON对象中传递给接口,在封装json数据时可以定义一个规范的数据模板,所有请求这都使用同一个数据模板
封装请求信息类时会对每个请求字段信息做校验,验证前端传来的信息是否符合规则,如果不符合则直接返回。因此我们需要使用jakarta.validation
依赖提供的参数校验功能。
这个校验功能只在请求信息中使用,而封装统一请求信息只在common_utils
模块中,因此就将此依赖添加到该默认pom.xml
文件中
common com.bruce 0.0.1-SNAPSHOT 4.0.0 common_utils jakarta.validation jakarta.validation-api 2.0.2
统一请求数据模板被各个业务模块调用,它属于公共模块因此将它在common
模块common_utils
下,和统一返回数据格式在同一个目录下。
在commonutils
包下新建B
类设计统一请求信息格式,根据封装json结构设计如下
package com.bruce.commonutils;import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.Serializable;/*** @author bruce* @create 2023/3/9 19:41*/
@Data
@ApiModel("基础请求")
public class B implements Serializable {@NotNull(message = "渠道参数错误")@ApiModelProperty(value = "渠道", example = "AppStore")private String channelId;@NotNull(message = "设备ID参数错误")@ApiModelProperty(value = "设备ID", example = "C3C1A3EE-6B32-4C06-A83C-DFCC0A31A331")private String deviceNo;@NotNull(message = "请求端设备种类参数错误")@ApiModelProperty(value = "请求端设备种类", example = "Android iOS PC")private String deviceType;@NotNull(message = "请求端版本号参数错误")@ApiModelProperty(value = "请求端版本号", example = "1.3.2")private String version;@NotNull(message = "请求端版本参数错误")@ApiModelProperty(value = "请求端版本", example = "001003002")private Integer versionCode;@ApiModelProperty(value = "请求端产品", example = "wenyizhongguo")private String clientType;@ApiModelProperty(value = "分辨率", example = "1280*720")private String resolution;@ApiModelProperty(value = "系统版本", example = "8.0")private String osVersion;@ApiModelProperty(value = "厂商", example = "iPhone 8 Plus")private String deviceName;@ApiModelProperty(value = "定位信息")private String adCode;@ApiModelProperty(value = "网络类型", example = "5G, wifi")private String networkAccess;@Valid@ApiModelProperty("请求内容")private T data;
}
1.统一请求放在了公共的包中,业务模块使用该功能是跨模块调用,因此需要在业务模块中加上common_utils
模块依赖。
例如在service
模块的pom.xml
文件中导入common_utils
依赖,如果已存在则忽略。
com.bruce common_utils 0.0.1-SNAPSHOT
2.在业务模块的启动类上使用@ComponentScan(basePackages = {“com.bruce”})注解设置包扫描路径,扫描到common包就可以。
在请求接口遇到异常时会返回一个异常信息,这个异常信息通常都是java异常类返回的信息。用户都是看了之后不知道是什么意思,因此我们将这些返回的的异常信息统一进行处理,返回用户能够看懂的信息。
封装统一异常模板包含三个类型,之所以将他们分类就是为了在众多的异常中能够快速定位出问题出现在代码的位置和原因。
返回全局异常信息
全局异常类型是一个通用类型,他没有特殊含义,只要是异常信息都可以通过它返回给调用者。
特定异常处理
创建一些特别异常类型,用来突出显示某些问题,例如空指针异常类型、除数不能为0异常类型等等
自定义异常处理
自定义一些与业务相关的异常信息,例如登录没有权限异常、下单失败异常等等
封装全局异常类时需要依赖统一返回信息对象,所以需要在service_base
模块中引入commonutils
依赖
com.bruce common_utils 0.0.1-SNAPSHOT
1.在common
公共模块的service_base
公共模块下封装异常信息模板
2.在该模块的com.bruce.servicebase
包下新建exceptionhandler
包
3.在该包下新建GlobalExceptionHandler
类封装全局异常类
package com.bruce.servicebase.exceptionhandler;import com.bruce.commonutils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;/*** @author bruce* @create 2023/3/9 20:25*/
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {//设置哪些异常调用这个统一异常方法@ExceptionHandler(Exception.class)//返回数据@ResponseBodypublic R error(Exception e) {e.printStackTrace();return R.error().message("执行了全局异常处理");}
}
1.统一异常放在了公共的包中,业务模块使用该功能是跨模块调用,因此需要在业务模块中加上service_base
公共模块依赖。
例如在service
模块的pom.xml
文件中导入service_base
依赖,如果已存在则忽略。
com.bruce service_base 0.0.1-SNAPSHOT
2.在业务启动类中使用@ComponentScan注解扫描common的包,以便能够将统一异常处理类进行注册。
特定异常处理和全局异常处理原理相同,唯一的区别就是给某个异常类设置一个专用的返回信息。例如被除数为零时会调用ArithmeticException异常类,我们可以专为该异常类添加一个异常信息。
在全局异常类GlobalExceptionHandler
封装特定异常类信息
package com.bruce.servicebase.exceptionhandler;import com.bruce.commonutils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;/*** @author bruce* @create 2023/3/9 20:25*/
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {//设置哪些异常调用这个统一异常方法@ExceptionHandler(Exception.class)//返回数据@ResponseBodypublic R error(Exception e) {e.printStackTrace();return R.error().message("执行了全局异常处理");}//设置特定异常信息@ExceptionHandler(ArithmeticException.class)@ResponseBodypublic R error(ArithmeticException e) {e.printStackTrace();return R.error().message("特定异常:被除数不能为零");}
}
当全局异常中没有我们想要的异常类型时,我们可以自己创造一个异常类型,用到我们的业务中。在不同的业务中返回不同的自定义信息。
在exceptionhandler
包新建一个自定义异常类BruceException
类,继承RuntimeException异常类。该类定义异常信息的属性。
package com.bruce.servicebase.exceptionhandler;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** @author bruce* @create 2023/3/9 20:48*/
@Data
//生成有参构造器
@AllArgsConstructor
//生成无餐构造器
@NoArgsConstructor
public class BruceException extends RuntimeException {//定义状态码private Integer code;//定义异常信息private String msg;
}
在全局异常类GlobalExceptionHandler
封装自定义异常类信息
package com.bruce.servicebase.exceptionhandler;import com.bruce.commonutils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;/*** @author bruce* @create 2023/3/9 20:25*/
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {//设置哪些异常调用这个统一异常方法@ExceptionHandler(Exception.class)//返回数据@ResponseBodypublic R error(Exception e) {e.printStackTrace();return R.error().message("执行了全局异常处理");}//设置特定异常信息@ExceptionHandler(ArithmeticException.class)@ResponseBodypublic R error(ArithmeticException e) {//将日志输出到error文件中log.error(ExceptionUtil.getMessage(e));e.printStackTrace();return R.error().message("特定异常:被除数不能为零");}//自定义异常类型@ExceptionHandler(BruceException.class)@ResponseBodypublic R error(BruceException e) {e.printStackTrace();//动态返回异常状态码和异常信息return R.error().code(e.getCode()).message(e.getMsg());}
}
在业务中需要抛出异常的位置,手动调用自定义的异常类,抛出自定义异常信息。
try {int a = 10/0;
}catch(Exception e) {//给自定义异常类传入状态码和异常信息throw new BruceException(20001,"出现自定义异常");
}
介绍SpringBoot项目如何对日志进行统一处理,比如将info、error、warn级别的日志输出到文件,设置日志格式等。
封装日志模板包含如下几个内容
在业务模块中创建配置文件封装日志,例如在 service_user
用户模块的resources
文件夹下新建logback-spring.xml
配置文件,配置日志内容。
配置文件分为两个部分
日志级别设置介绍
logback ${CONSOLE_LOG_PATTERN} UTF-8 ${log.path}/log_info.log %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n UTF-8 ${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log 100MB 15 INFO ACCEPT DENY ${log.path}/log_warn.log %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n UTF-8 ${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log 100MB 15 warn ACCEPT DENY ${log.path}/log_error.log %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n UTF-8 ${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log 100MB 15 ERROR ACCEPT DENY
上面的配置文件已经配置好了日志输出的格式,运行项目后就会自动在配置文件中指定的路径下创建info.log、error.log、warn.log三个日志文件。
通常代码报错都会自动调用异常类,抛出异常信息。因此我们在异常类上添加注解,就可以将异常信息都输出到error.log文件中。
此处会用到统一异常信息处理知识,因此需要先配置好统一异常信息的内容。
在异常类上配置日志
service_base
公共模块中打开封装全局异常类GlobalExceptionHandler
,在该类上添加@Slf4j注解。package com.bruce.servicebase.exceptionhandler;import com.bruce.commonutils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;/*** @author bruce* @create 2023/3/9 20:25*/
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {//设置哪些异常调用这个统一异常方法@ExceptionHandler(Exception.class)//返回数据@ResponseBodypublic R error(Exception e) {e.printStackTrace();return R.error().message("执行了全局异常处理");}//设置特定异常信息@ExceptionHandler(ArithmeticException.class)@ResponseBodypublic R error(ArithmeticException e) {//将异常日志输出到error文件中,只有错误信息没有上下文栈信息log.error(e.getMessage());e.printStackTrace();return R.error().message("特定异常:被除数不能为零");}//自定义异常类型@ExceptionHandler(BruceException.class)@ResponseBodypublic R error(BruceException e) {e.printStackTrace();//动态返回异常状态码和异常信息return R.error().code(e.getCode()).message(e.getMsg());}
}
在service_base
公共模块的 exceptionhandler
包新建ExceptionUtil
类,这个类的作用是将异常栈信息输出到错误日志文件中
package com.bruce.servicebase.exceptionhandler;import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;/*** @author bruce* @create 2023/3/9 20:43*/
public class ExceptionUtil {public static String getMessage(Exception e) {StringWriter sw = null;PrintWriter pw = null;try {sw = new StringWriter();pw = new PrintWriter(sw);// 将出错的栈信息输出到printWriter中e.printStackTrace(pw);pw.flush();sw.flush();} finally {if (sw != null) {try {sw.close();} catch (IOException e1) {e1.printStackTrace();}}if (pw != null) {pw.close();}}return sw.toString();}
}
在全局异常类GlobalExceptionHandler
通过log.err方法将异常输出到错误日志
//设置特定异常信息@ExceptionHandler(ArithmeticException.class)@ResponseBodypublic R error(ArithmeticException e) {//调用ExceptionUtil工具路,将异常栈信息输出到错误日志error文件中log.error(ExceptionUtil.getMessage(e));// 控制台输出异常信息e.printStackTrace();return R.error().message("特定异常:被除数不能为零");}
在每个业务模块的application.properties
文件中将mybatis日志删掉或禁用,否则日志插件会有冲突。
例如 service_user
用户模块的application.properties
文件中将下面的日志内容删除。
#mybatis日志
#logging.level.root=INFO
#mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
我们通过开发一个用户模块业务验收搭建的《搭建SpringBoot多模块微服务项目脚手架》各个功能是否可以正常使用。
1.启动service_user
模块服务,点击UserApplication
启动类启动服务。
2.在浏览器输入http://localhost:8001/swagger-ui/index.html
查看Swagger
MybatisPlus功能都在service_user
模块上验证,通过mybatisplus操作增删改查业务,验收ID自增长、创建时间和修改时间自动填充、分页查询、逻辑删除功能。
在service_user
模块的entity
包中打开User
实体类
id
属性上添加 @TableId 注解,自动生成ID。gmtCreate
属性 和 gmtModified
属性上添加@TableField注解,自动填充内容isDeleted
属性上添加 @TableLogic 注解实现逻辑删除package com.bruce.service_user.entity;import com.baomidou.mybatisplus.annotation.*;import java.util.Date;import java.io.Serializable;import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;/*** * *
** @author bruce* @since 2023-03-09*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="User对象", description="")
public class User implements Serializable {private static final long serialVersionUID = 1L;@ApiModelProperty(value = "用户ID")@TableId(value = "id", type = IdType.ID_WORKER_STR)private String id;@ApiModelProperty(value = "姓名")private String name;@ApiModelProperty(value = "年龄")private Integer age;@ApiModelProperty(value = "邮箱")private String email;@ApiModelProperty(value = "逻辑删除 1(true)已删除, 0(false)未删除")@TableLogicprivate Boolean isDeleted;@ApiModelProperty(value = "创建时间")@TableField(fill = FieldFill.INSERT)private Date gmtCreate;@ApiModelProperty(value = "更新时间")@TableField(fill = FieldFill.INSERT_UPDATE)private Date gmtModified;}
新增业务用来验证ID自增长、创建时间和修改时间自动填充功能。
在service_user
模块,controller
包中UserController
类中开发新增用户接口
controller层开发新增用户接口
package com.bruce.service_user.controller;import com.bruce.commonutils.B;
import com.bruce.commonutils.R;
import com.bruce.service_user.entity.User;
import com.bruce.service_user.service.UserService;
import com.bruce.servicebase.exceptionhandler.BruceException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;/*** * 前端控制器*
** @author bruce* @since 2023-03-09*/
@Api(tags = "用户管理")
@RestController
@RequestMapping("/service_user/user")
public class UserController {@AutowiredUserService userService;@ApiOperation(value = "新增用户")@PostMapping("addUser")public R addUser(@RequestBody B b) {int userId = userService.addUser(b);if (userId < 1) {throw new BruceException(20003, "新增用户失败");}return R.ok();}
}
service层实现新增用户业务逻辑
package com.bruce.service_user.service.impl;import com.bruce.commonutils.B;
import com.bruce.service_user.entity.User;
import com.bruce.service_user.mapper.UserMapper;
import com.bruce.service_user.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;/*** * 服务实现类*
** @author bruce* @since 2023-03-09*/
@Service
public class UserServiceImpl extends ServiceImpl implements UserService {@Overridepublic int addUser(B b) {User user = b.getData();int insert = baseMapper.insert(user);return insert;}
}
调用新增用户接口
在Swagger上点击新增用户接口,填写如下请求内容。并执行Execute。
{"adCode": "string","channelId": "AppStore","clientType": "wenyizhongguo","data": {"age": 10,"email": "user@163.com","name": "张三"},"deviceName": "iPhone 8 Plus","deviceNo": "C3C1A3EE-6B32-4C06-A83C-DFCC0A31A331","deviceType": "Android iOS PC","networkAccess": "5G, wifi","osVersion": "8.0","resolution": "1280*720","version": "1.3.2","versionCode": 1003002
}
查看控制台输出了新增成功的日志,查看mysql数据库新增了一条数据,从数据中查看id为自动生成,创建时间和修改时间自动填充。删除状态填充了默认值。
+---------------------+--------+------+--------------+------------+---------------------+---------------------+
| id | name | age | email | is_deleted | gmt_create | gmt_modified |
+---------------------+--------+------+--------------+------------+---------------------+---------------------+
| 1634037440222609409 | 张三 | 10 | user@163.com | 0 | 2023-03-10 11:44:19 | 2023-03-10 11:44:19 |
+---------------------+--------+------+--------------+------------+---------------------+---------------------+
通过分页查询用户列表,验证封装的分页查询功能。
controller层开发分页查询接口
在service_user
模块,controller
包中UserController
类中开发分页查询用户接口
@ApiOperation(value = "无条件分页查询用户")@GetMapping("pageUser/{page}/{limit}")public R queryUserList(@ApiParam(name = "page", value = "当前页码", required = true)@PathVariable long page,@ApiParam(name = "limit", value = "每页记录数", required = true)@PathVariable long limit) {//创建分页查询对象Page userPage = new Page<>(page, limit);//调用分页查询对象,传入分页对象和查询条件,结果封装到userPage对象userService.page(userPage, null);//获取查询结果List records = userPage.getRecords();//获取查询总条数long size = userPage.getSize();//封装返回结果Map map = new HashMap<>();map.put("total", size);map.put("data", records);return R.ok().message("成功").data(map);}
调用接口查询用户
在Swagger上点击查询用户接口,填写当前页和每页条数。并执行Execute。返回查询结果
{"success": true,"code": 200,"message": "成功","data": {"total": 10,"data": [{"id": "1634037440222609409","name": "张三","age": 10,"email": "user@163.com","isDeleted": false,"gmtCreate": "2023-03-10T03:44:19.000+00:00","gmtModified": "2023-03-10T03:44:19.000+00:00"}]}
}
通过删除用户,验证封装的逻辑删除功能。
controller层开发删除用户接口
在service_user
模块,controller
包中UserController
类中开发删除用户接口
@ApiOperation(value = "根据ID删除用户", notes = "逻辑删除用户")@DeleteMapping("{id}")public R removeById(@PathVariable String id) {boolean flag = userService.removeById(id);if (flag) {return R.ok();} else {return R.error();}}
调用接口删除用户
在Swagger上点击删除用户接口,填写用户id。并执行Execute。通过mysql查询用户信息,is_deleted
字段变为1.
+---------------------+--------+------+--------------+------------+---------------------+---------------------+
| id | name | age | email | is_deleted | gmt_create | gmt_modified |
+---------------------+--------+------+--------------+------------+---------------------+---------------------+
| 1634037440222609409 | 张三 | 10 | user@163.com | 1 | 2023-03-10 11:44:19 | 2023-03-10 11:44:19 |
+---------------------+--------+------+--------------+------------+---------------------+---------------------+
1 row in set (0.00 sec)
上面示例中开发的接口返回类型使用我们封装的R类对象,请求参数类型使用我们封装的B类型对象。
@ApiOperation(value = "新增用户")@PostMapping("addUser")public R addUser(@RequestBody B b) {int userId = userService.addUser(b);if (userId < 1) {throw new BruceException(20003, "新增用户失败");}return R.ok();}
通过一个被除数为0验证下发生异常后调用我们封装好的ArithmeticException
异常,返回被除数不能为0信息。
controller层开发特定异常接口
在service_user
模块,controller
包中UserController
类中开发特定异常接口
注意:在接口中只定义了成功返回的信息,没有判断失败时返回的信息,是因为它发生异常后会走封装好的特定异常方法,在该方法中定义好了返回信息格式。
@ApiOperation(value = "特定异常", notes = "被除数为0异常 ArithmeticExceptio")@GetMapping("exception/{first}/{secont}")public R myException(@ApiParam(name = "first", value = "除数", required = true)@PathVariable long first,@ApiParam(name = "secont", value = "被除数", required = true)@PathVariable long secont) {long l = first / secont;return R.ok().message("成功").data("data", l);}
调用特定异常接口
在Swagger上点击特定异常接口,除数填写1,被除数填写0。并执行Execute。返回信息是特定异常封装的返回信息。
{"success": false,"code": 60000,"message": "特定异常:被除数不能为零","data": {}
}
通过一个被除数为0验证下发生异常后调用我们封装好的BruceException
自定义异常类,返回传入的code和message信息。
controller层开发特定异常接口
在service_user
模块,controller
包中UserController
类中开发特定异常接口
@ApiOperation(value = "自定义异常", notes = "被除数为0异常 自定义异常信息")@GetMapping("exception/{first}/{secont}")public R myException(@ApiParam(name = "first", value = "除数", required = true)@PathVariable long first,@ApiParam(name = "secont", value = "被除数", required = true)@PathVariable long secont) {try {long l = first / secont;return R.ok().message("成功").data("data", l);} catch (Exception e) {//实例化自定义异常类对象,传入code和messagethrow new BruceException(3001, "自定义异常");}}
调用自定义异常接口
在Swagger上点击自定义异常接口,除数填写1,被除数填写0。并执行Execute。返回信息是自定义异常封装的返回信息。
{"success": false,"code": 3001,"message": "自定义异常","data": {}
}
我们将日志封装后根据日志类型分别输出到 log_info.log
、 log_warn.log
、 log_error.log
三个文件中,上面操作业务有成功和和异常的,因此我们只要查看下日志文件就可以确认它是否可用。
每次使用SpringBoot开发微服务项目时都要搭建一次完整的开发环境过程都很长,配置也很复杂繁琐。但是我们将这个过程做成一个模板并命名为脚手架,那么就不一样了。
将《搭建SpringBoot多模块微服务项目脚手架》上传到GitHub上,每次需要的时候只要下载下来,简单的修改下包名就可以开发业务,这个体验就很舒服了。
《搭建SpringBoot多模块微服务项目脚手架》 源代码已在Gitee仓库开源,每个想学习的朋友都可以下载练手。
只做为学习,勿做他用!
Gitee仓库项目地址:https://gitee.com/brucexiaogui/spring-boot-hand-ladder