• 总结一下前后端分离业务流程


    目录

     1.创建一个返回统一结果的处理类

    2.定义成功失败的枚举

    3.自定义异常以及异常处理

    4.控制层例子

    5.来看前端


    构造

     1.创建一个返回统一结果的处理类

    1. package com.atguigu.eduservice;
    2. import io.swagger.annotations.Api;
    3. import io.swagger.annotations.ApiModelProperty;
    4. import lombok.Data;
    5. import java.util.HashMap;
    6. import java.util.Map;
    7. /**
    8. * 统一返回结果类
    9. * 调用结果
    10. * 对success,code,message进行设置->返回调用者的对象方便链式编程->以此继续调用
    11. */
    12. @Data
    13. public class R {
    14. @ApiModelProperty(value = "是否成功")
    15. private Boolean success;
    16. @ApiModelProperty(value = "返回码")
    17. private Integer code;
    18. @ApiModelProperty(value = "返回消息")
    19. private String message;
    20. @ApiModelProperty(value = "返回数据")
    21. private Map data = new HashMap();
    22. //设置一个私有构造让别人不能修改我的属性和方法,只能用规定的static成员
    23. private R() {
    24. }
    25. public static R ok(){
    26. R r = new R();
    27. r.setSuccess(true);
    28. r.setCode(ResultCode.SUCCESS);
    29. r.setMessage("成功");
    30. return r;
    31. }
    32. public static R error(){
    33. R r = new R();
    34. r.setSuccess(false);
    35. r.setCode(ResultCode.ERROR);
    36. r.setMessage("失败");
    37. return r;
    38. }
    39. /**
    40. * 对状态码以及信息(success,code,data)进行设置
    41. * @param success
    42. * @return
    43. */
    44. public R success(Boolean success){
    45. this.setSuccess(success);
    46. return this;
    47. }
    48. public R message(String message){
    49. this.setMessage(message);
    50. return this;
    51. }
    52. public R code(Integer code){
    53. this.setCode(code);
    54. return this;
    55. }
    56. public R data(String key, Object value){
    57. this.data.put(key, value);
    58. return this;
    59. }
    60. public R data(Map map){
    61. this.setData(map);
    62. return this;
    63. }
    64. }

    2.定义成功失败的枚举

    1. package com.atguigu.eduservice;
    2. public interface ResultCode {
    3. //定义成功失败的编码
    4. public static Integer SUCCESS = 20000;
    5. public static Integer ERROR = 20001;
    6. }

    3.自定义异常以及异常处理

     自定义异常类

    1. package com.atguigu.eduservice.exceptionHandler;
    2. import io.swagger.annotations.ApiModelProperty;
    3. import lombok.AllArgsConstructor;
    4. import lombok.Data;
    5. import lombok.NoArgsConstructor;
    6. @Data
    7. @AllArgsConstructor
    8. @NoArgsConstructor
    9. /**
    10. * 自定义异常
    11. */
    12. public class GuliException extends RuntimeException{
    13. @ApiModelProperty(value = "状态码")
    14. private Integer code;
    15. private String msg;
    16. }

     统一异常处理类

    核心:@ControllerAdvice+@Slf4j+@ExceptionHandler(xxx.class)

    1. package com.atguigu.eduservice.exceptionHandler;
    2. import com.atguigu.eduservice.R;
    3. import lombok.extern.slf4j.Slf4j;
    4. import org.springframework.web.bind.annotation.ControllerAdvice;
    5. import org.springframework.web.bind.annotation.ExceptionHandler;
    6. import org.springframework.web.bind.annotation.ResponseBody;
    7. /**
    8. * 统一异常处理类
    9. */
    10. @ControllerAdvice
    11. @Slf4j//logback日志
    12. public class GlobalExceptionHandler {
    13. @ResponseBody
    14. @ExceptionHandler(Exception.class)//指定在哪里出现的异常会被处理
    15. public R GlobalError(Exception e) {
    16. e.printStackTrace();
    17. return R.error().message("执行全局异常处理");
    18. }
    19. /**
    20. * 优先执行特定异常
    21. * 特定异常处理
    22. */
    23. @ResponseBody
    24. @ExceptionHandler(ArithmeticException.class)//指定在哪里出现的异常会被处理
    25. public R ArithmeticError(Exception e) {
    26. e.printStackTrace();
    27. return R.error().message("ArithmeticException出现");
    28. }
    29. /**
    30. * 自定义异常
    31. */
    32. @ExceptionHandler
    33. @ResponseBody
    34. public R error(GuliException e) {
    35. //会把日志信息写到文件中
    36. log.error(e.getMsg());
    37. e.printStackTrace();
    38. return R.error().message(e.getMsg()).code(e.getCode());
    39. }
    40. }

    对字段进行填充

    1. package com.atguigu.eduservice.handler;
    2. import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
    3. import org.apache.ibatis.reflection.MetaObject;
    4. import org.springframework.stereotype.Component;
    5. import java.nio.channels.NetworkChannel;
    6. import java.util.Date;
    7. @Component
    8. public class MyMetaObjectHandler implements MetaObjectHandler {
    9. /**
    10. * 对插入字段进行自动填充->这里就是创建时间和修改时间我们会自动填充
    11. *
    12. * @param metaObject
    13. */
    14. @Override
    15. public void insertFill(MetaObject metaObject) {
    16. this.setFieldValByName("gmtCreate", new Date(), metaObject);
    17. this.setFieldValByName("gmtModified", new Date(), metaObject);
    18. }
    19. @Override
    20. public void updateFill(MetaObject metaObject) {
    21. this.setFieldValByName("gmtModified", new Date(), metaObject);
    22. }
    23. }

    4.控制层例子

    1. package com.atguigu.eduservice.controller;
    2. import com.atguigu.eduservice.R;
    3. import com.atguigu.eduservice.entity.EduTeacher;
    4. import com.atguigu.eduservice.entity.vo.TeacherQuery;
    5. import com.atguigu.eduservice.service.EduTeacherService;
    6. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    7. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
    8. import io.swagger.annotations.Api;
    9. import io.swagger.annotations.ApiOperation;
    10. import org.apache.commons.lang3.StringUtils;
    11. import org.springframework.beans.factory.annotation.Autowired;
    12. import org.springframework.web.bind.annotation.*;
    13. import java.util.HashMap;
    14. import java.util.List;
    15. /**
    16. *

    17. * 讲师 前端控制器
    18. *

    19. * http://localhost:8001/eduservice/edu-teacher/findAll
    20. *
    21. * @author testjava
    22. * @since 2022-07-05
    23. */
    24. @Api(description = "讲师管理")
    25. @RestController
    26. @CrossOrigin
    27. @RequestMapping("/eduservice/teacher")
    28. public class EduTeacherController {
    29. @Autowired
    30. private EduTeacherService teacherService;
    31. /**
    32. * 1.查询教师表中所有数据
    33. * SELECT id,name,intro,career,level,avatar,sort,is_deleted,gmt_create,gmt_modified FROM edu_teacher WHERE is_deleted=0
    34. */
    35. @ApiOperation(value = "所有讲师")
    36. @GetMapping("findAll")
    37. public R findAllTeacher() {
    38. List<EduTeacher> list = teacherService.list(null);
    39. return R.ok().data("items", list);
    40. }
    41. /**
    42. * 2.逻辑删除讲师的方法:rest风格来一手
    43. */
    44. @ApiOperation(value = "根据逻辑删除讲师")
    45. @DeleteMapping("{id}")
    46. public R removeTeacher(@PathVariable String id) {
    47. boolean flag = teacherService.removeById(id);
    48. System.out.println("删除成功:" + flag);
    49. //具体判断进行返回
    50. if (flag) {
    51. return R.ok();
    52. } else {
    53. return R.error();
    54. }
    55. }
    56. /**
    57. * 3.分页查询讲师
    58. * SELECT id,name,intro,career,level,avatar,sort,is_deleted,gmt_create,gmt_modified FROM edu_teacher WHERE is_deleted=0 LIMIT 0,3
    59. */
    60. @GetMapping("pageTeacher/{current}/{limit}")
    61. public R pageListTeacher(@PathVariable long current, @PathVariable long limit) {
    62. //创建page对象
    63. Page<EduTeacher> teacherPage = new Page<>(current, limit);
    64. //调用方法进行分页,会将分页的数据封装到teacherPage里面
    65. teacherService.page(teacherPage, null);
    66. //总记录数
    67. long total = teacherPage.getTotal();
    68. //得到分页后数据集合
    69. List<EduTeacher> records = teacherPage.getRecords();
    70. HashMap map = new HashMap();
    71. map.put("total", total);
    72. map.put("rows", records);
    73. return R.ok().data(map);
    74. }
    75. /**
    76. * 4.多条件组合查询
    77. * 讲师级别,入住时间,名称...
    78. * 多条件:我们可以将条件值传入对象中,然后将对象传递到接口中(vo)
    79. * PageHelper的话调用startPage然后封装到PageInfo下即可
    80. * 这里的TeacherQuery也可以用@RequestBody来传递数据->Post提交
    81. * 传递的为Json数据,将Json数据封装到对象里面
    82. * SELECT id,name,intro,career,level,avatar,sort,is_deleted,gmt_create,gmt_modified FROM edu_teacher WHERE is_deleted=0 ORDER BY gmt_create DESC LIMIT 0,3 */
    83. @PostMapping("pageTeacherCondition/{current}/{limit}")
    84. public R pageTeacherCondition(@PathVariable long current, @PathVariable long limit, @RequestBody(required = false) TeacherQuery teacherQuery) {
    85. //创建Page对象
    86. Page<EduTeacher> teacherPage = new Page<>(current, limit);
    87. //wrapper构建条件过滤
    88. QueryWrapper<EduTeacher> wrapper = new QueryWrapper<>();
    89. String name = teacherQuery.getName();
    90. Integer level = teacherQuery.getLevel();
    91. String begin = teacherQuery.getBegin();
    92. String end = teacherQuery.getEnd();
    93. wrapper.like(StringUtils.isNotBlank(name), "name", name)
    94. .like(level != null, "level", level)
    95. .ge(begin != null, "gmt_create", begin)
    96. .le(end != null, "gmt_create", end);
    97. //按照时间降序处理
    98. wrapper.orderByDesc("gmt_create");
    99. //对过滤条件进行封装进而->得到分页数据
    100. teacherService.page(teacherPage, wrapper);
    101. long total = teacherPage.getTotal();
    102. List<EduTeacher> records = teacherPage.getRecords();
    103. return R.ok().data("total", total).data("rows", records);
    104. }
    105. /**
    106. *5.添加讲师
    107. */
    108. @ApiOperation(value = "添加讲师")
    109. @PostMapping("addTeacher")
    110. public R addTeacher(@RequestBody EduTeacher eduTeacher){
    111. boolean save = teacherService.save(eduTeacher);
    112. return save?R.ok():R.error();
    113. }
    114. /**
    115. * 6.修改讲师
    116. * 根据讲师id先进行查询,然后修改
    117. * UPDATE edu_teacher SET name=?, intro=?, career=?, level=?, avatar=?, sort=?, gmt_modified=? WHERE id=? AND is_deleted=0
    118. */
    119. @GetMapping("getTeacher/{id}")
    120. public R getTeacher(@PathVariable String id){
    121. EduTeacher eduTeacher = teacherService.getById(id);
    122. return R.ok().data("teacher",eduTeacher);
    123. }
    124. @ApiOperation(value = "修改讲师")
    125. @PostMapping("updateTeacher")
    126. public R updateTeacher(@RequestBody EduTeacher eduTeacher){
    127. boolean flag = teacherService.updateById(eduTeacher);
    128. if(flag){
    129. return R.ok();
    130. }else{
    131. return R.error();
    132. }
    133. }
    134. }

    返回我们的json数据

    5.来看前端

    5.1在我们的config下配置了路由信息dev.env.js

     

     9001是我们nginx负载均衡的端口

    1. 'use strict'
    2. const merge = require('webpack-merge')
    3. const prodEnv = require('./prod.env')
    4. module.exports = merge(prodEnv, {
    5. NODE_ENV: '"development"',
    6. // BASE_API: '"https://easy-mock.com/mock/5950a2419adc231f356a6636/vue-admin"',
    7. BASE_API: '"http://localhost:9001"',
    8. })

    5.2定义我们的后台api

     里面调用了我们后台的接口

    1. import request from '@/utils/request'
    2. export default {
    3. //1.讲师列表(条件查询分页)
    4. //参数分别为当前页,每页记录数,
    5. getTeacherListPage(current,limit,teacherQuery) {
    6. return request({
    7. url: `/eduservice/teacher/pageTeacherCondition/${current}/${limit}`,
    8. method: 'post',
    9. //teacherQuery条件对象,后端使用RequestBody传输数据
    10. //data表示对象传唤成json传输
    11. data: teacherQuery
    12. })
    13. },
    14. deleteTeacherId(id){
    15. return request({
    16. url: `/eduservice/teacher/${id}`,
    17. method: 'delete'
    18. //teacherQuery条件对象,后端使用RequestBody传输数据
    19. //data表示对象传唤成json传输
    20. // data: teacherQuery
    21. })
    22. },
    23. addTeacher(teacher){
    24. return request({
    25. url: '/eduservice/teacher/addTeacher',
    26. method: 'post',
    27. //将teacher转为json传输数据
    28. data: teacher
    29. })
    30. },
    31. getTeacherInfo(id){
    32. return request({
    33. url: `/eduservice/teacher/getTeacher/${id}`,
    34. method: 'get'
    35. })
    36. },
    37. //修改讲师
    38. updateTeacherInfo(teacher){
    39. return request({
    40. url: `/eduservice/teacher/updateTeacher`,
    41. method: 'post',
    42. data: teacher
    43. })
    44. },
    45. //2.查询所有的讲师
    46. getListTeacher(){
    47. return request({
    48. url: `/eduservice/teacher/findAll`,
    49. method: 'get'
    50. })
    51. }
    52. }

    5.3然后再在具体页面调用封装后台接口的js文件,调用里面的方法