谷粒学院(三)讲师管理模块(后端) | swagger | 统一日志 | 统一返回结果(二)

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 谷粒学院(三)讲师管理模块(后端) | swagger | 统一日志 | 统一返回结果

四、统一返回结果对象

1、统一返回数据格式

项目中我们会将响应封装成json返回,一般我们会将所有接口的数据格式统一, 使前端(iOS Android, Web)对数据的操作更一致、轻松。


一般情况下,统一返回数据格式没有固定的格式,只要能描述清楚返回的数据状态以及要返回的具体数据就可以。但是一般会包含状态码、返回消息、数据这几部分内容


例如,我们的系统要求返回的基本数据格式如下:


携带数据成功

{
  "success": true,
  "code": 20000,
  "message": "成功",
  "data": {
    "items": [
      {
        "id": "1",
        "name": "刘德华",
        "intro": "毕业于师范大学数学系,热爱教育事业,执教数学思维6年有余"
      }
    ]
  }
}
  • 携带数据成功(分页)
{
  "success": true,
  "code": 20000,
  "message": "成功",
  "data": {
    "total": 17,
    "rows": [
      {
        "id": "1",
        "name": "刘德华",
        "intro": "毕业于师范大学数学系,热爱教育事业,执教数学思维6年有余"
      }
    ]
  }
}
  • 无返回数据成功
{
  "success": true,
  "code": 20000,
  "message": "成功",
  "data": {}
}
  • 无返回数据失败
{
  "success": false,
  "code": 20001,
  "message": "失败",
  "data": {}
}
  • 因此,我们统一结果
{
  "success": 布尔, //响应是否成功
  "code": 数字, //响应码
  "message": 字符串, //返回消息
  "data": HashMap //返回数据,放在键值对中
}

2、统一结果返回类

  • 在common模块下创建子模块common_utils
  • 创建接口 定义返回码—创建包 com.rg.commonutils,创建接口 ResultCode
public interface ResultCode {
    public static Integer SUCCESS = 20000;//成功
    public static Integer ERROR = 20001;//失败
}
  • 创建结果类—创建 R
@Data
public class R {
    @ApiModelProperty(value = "是否成功")
    private Boolean success;
    @ApiModelProperty(value = "返回码")
    private Integer code;
    @ApiModelProperty(value = "返回消息")
    private String message;
    @ApiModelProperty(value = "返回数据")
    private Map <String, Object> data = new HashMap <String, Object>();
    private R(){}  //构造方法私有化. 目的:禁止随意new 方法,只能使用我们定义的方法.
    public static R ok(){//定义成功方法
        R r = new R();
        r.setSuccess(true);
        r.setCode(ResultCode.SUCCESS);
        r.setMessage("成功");
        return r;//为了链式编程
    }
    public static R error(){//定义失败方法
        R r = new R();
        r.setSuccess(false);
        r.setCode(ResultCode.ERROR);
        r.setMessage("失败");
        return r;//为了链式编程
    }
    //自定义属性的相关方法(带链式编程功能)
    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<String,Object> map){
        this.setData(map);
        return this;
    }
}

3、统一返回结果的使用

  • 在service模块中添加依赖—common_utils
  • 修改Controller中的返回结果
//1.查询讲师所有数据  使用Rest风格..
@ApiOperation("所有讲师列表")
@GetMapping("findAll")
public List <EduTeacher> findAll() {
    List <EduTeacher> eduTeacherList = eduTeacherService.list(null);
    return eduTeacherList;
}
//2.通过id逻辑删除讲师
@ApiOperation("根据ID删除讲师")
@DeleteMapping("removeById/{id}")
public R removeById(@ApiParam(name = "id", value = "讲师ID", required = true) @PathVariable String id) {
    boolean flag = eduTeacherService.removeById(id);
    if (flag) {
        return R.ok();
    } else {
        return R.error();
    }
}

五、讲师分页查询

1、EduConfig中配置分页插件

/**
     * 分页插件
     */
@Bean
public PaginationInterceptor paginationInterceptor(){
    return new PaginationInterceptor();
}

2、EduTeacherController中添加分页方法

//3.分页查询讲师
@ApiOperation("分页查询讲师")
@GetMapping("pageList/{current}/{limit}")
public R pageList(@ApiParam(name = "current", value = "当前页码", required = true)
                  @PathVariable("current") Integer current,
                  @ApiParam(name = "limit", value = "每页记录数", required = true)
                  @PathVariable("limit") Integer limit) {
    Page <EduTeacher> page = new Page <>(current, limit);
    //进行分页查询
    eduTeacherService.page(page, null);//最后这些属性既可以通过page也可以通过iPage获取,因为分页后的数据会被重新封装到这些对象里面.
    // Map <String, Object> map = new HashMap <>();
    // map.put("total",page.getTotal());
    // map.put("rows", page.getRecords());
    // return R.ok().data(map);
    return R.ok().data("total", page.getTotal()).data("rows", page.getRecords());
}

六、讲师条件查询带分页

要求:根据讲师名称name,讲师头衔level、讲师入驻时间查询

1、创建查询对象

创建com.rg.eduservice.entiy.vo包,创建TeacherQuery类查询对象

@ApiModel(value = "Teacher查询对象",description = "讲师查询对象封装")
@Data
public class TeacherQuery implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "教师名称,模糊查询")
    private String name;
    @ApiModelProperty(value = "头衔 1高级讲师 2首席讲师")
    private Integer level;
    @ApiModelProperty(value = "查询开始时间", example = "2019-01-01 10:10:10")
    private String begin;
    @ApiModelProperty(value = "查询结束时间", example = "2019-12-01 10:10:10")
    private String end;
}

2、编写controller

//4.根据条件查询讲师
@ApiOperation("根据条件查询讲师")
@PostMapping("pageQuery/{current}/{limit}") //@RequestBody: 通过json传递数据,把数据封装到对象中. json数据只能封装到请求体中,所以就需要用到POST请求
public R pageQuery(@ApiParam(name = "current", value = "当前页码", required = true)
                   @PathVariable("current") Integer current,
                   @ApiParam(name = "limit", value = "每页记录数", required = true)
                   @PathVariable("limit") Integer limit,
                   @ApiParam(name = "teacherQuery",value = "查询条件",required = false) @RequestBody(required = false) TeacherQuery teacherQuery){//required = false,表示条件可有可无
    Page <EduTeacher> page = new Page <>(current, limit);
    //构建条件
    QueryWrapper <EduTeacher> wrapper = new QueryWrapper <>();
    String name = teacherQuery.getName();
    Integer level = teacherQuery.getLevel();
    String begin = teacherQuery.getBegin();
    String end = teacherQuery.getEnd();
    //mybatis我们学过动态sql,这里我们可以使用MP简化操作
    if(!StringUtils.isEmpty(name)){
        wrapper.like("name", name);
    }
    if(!StringUtils.isEmpty(level)){
        wrapper.eq("level", level);
    }
    if(!StringUtils.isEmpty(begin)){
        wrapper.ge("gmt_create", begin);
    }
    if(!StringUtils.isEmpty(end)){
        wrapper.le("gmt_modified", end);
    }
    eduTeacherService.page(page, wrapper);//分页查询
    return R.ok().data("total", page.getTotal()).data("rows", page.getRecords());
}

七、自动填充封装

1、在service-base中创建自动填充类

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        //这里设置的是属性名称,而非字段名称
        this.setFieldValByName("gmtCreate", new Date(), metaObject);
        this.setFieldValByName("gmtModified", new Date(), metaObject);
    }
    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("gmtModified", new Date(), metaObject);
    }
}

2、在实体类添加自动填充注解

70bea0f054210f00e0ca9215a679a917.png

八、讲师添加功能

1、在实体类添加自动填充注解

e73ad801edf22a2223a389cf46449177.png

2.EduTeacherController中新增方法

//5.添加讲师
@ApiOperation("添加讲师")
@PostMapping("addTeacher")
public R addTeacher(@ApiParam(value = "eduTeacher",name = "讲师信息") @RequestBody EduTeacher eduTeacher){
    boolean flag = eduTeacherService.save(eduTeacher);
    if (flag){
        return R.ok();
    }else{
        return R.error();
    }
}


3.Swagger中测试


7a1e72a1b9226bab45c52afd74bb60ba.png


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
3月前
|
负载均衡
|
3月前
|
运维 监控 关系型数据库
百度搜索:蓝易云【MYSQL四种管理日志详细介绍】
这四种管理日志对于MySQL服务器的性能监控、故障排查以及主从复制等方面都非常重要。在使用这些日志时,应根据具体需求来选择开启和配置,并定期清理和维护日志文件,以免占用过多磁盘空间。
73 0
|
9天前
|
监控 Java API
如何将不同业务模块产生的日志 分多文件记录
如何将不同业务模块产生的日志 分多文件记录
10 0
|
7天前
|
存储 监控 Java
|
12天前
|
存储 安全 Python
[python]使用标准库logging实现多进程安全的日志模块
[python]使用标准库logging实现多进程安全的日志模块
|
27天前
|
存储 算法 开发工具
Etcd/Raft 原理问题之Etcd-Raft是什么
Etcd/Raft 原理问题之Etcd-Raft是什么
|
12天前
|
JSON 安全 Go
[golang]使用logrus自定义日志模块
[golang]使用logrus自定义日志模块
|
27天前
|
存储 弹性计算 运维
可观测性体系问题之ECS管控对其所有日志的管理如何解决
可观测性体系问题之ECS管控对其所有日志的管理如何解决
26 0
|
2月前
Liunx怎么安装spdlog(这是用来管理日志部分)
Liunx怎么安装spdlog(这是用来管理日志部分)
35 7
|
1月前
|
Unix Python
Python代码示例:使用`syslog`模块进行日志记录
Python代码示例:使用`syslog`模块进行日志记录

热门文章

最新文章