目录
1.创建一个返回统一结果的处理类
2.定义成功失败的枚举
3.自定义异常以及异常处理
4.控制层例子
5.来看前端
构造
1.创建一个返回统一结果的处理类
package com.atguigu.eduservice;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
/**
* 统一返回结果类
* 调用结果
* 对success,code,message进行设置->返回调用者的对象方便链式编程->以此继续调用
*/
@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>();
//设置一个私有构造让别人不能修改我的属性和方法,只能用规定的static成员
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 r = new R();
r.setSuccess(false);
r.setCode(ResultCode.ERROR);
r.setMessage("失败");
return r;
}
/**
* 对状态码以及信息(success,code,data)进行设置
* @param success
* @return
*/
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;
}
}
2.定义成功失败的枚举
package com.atguigu.eduservice;
public interface ResultCode {
//定义成功失败的编码
public static Integer SUCCESS = 20000;
public static Integer ERROR = 20001;
}
3.自定义异常以及异常处理
自定义异常类
package com.atguigu.eduservice.exceptionHandler;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
/**
* 自定义异常
*/
public class GuliException extends RuntimeException{
@ApiModelProperty(value = "状态码")
private Integer code;
private String msg;
}
统一异常处理类
核心:@ControllerAdvice+@Slf4j+@ExceptionHandler(xxx.class)
package com.atguigu.eduservice.exceptionHandler;
import com.atguigu.eduservice.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;
/**
* 统一异常处理类
*/
@ControllerAdvice
@Slf4j//logback日志
public class GlobalExceptionHandler {
@ResponseBody
@ExceptionHandler(Exception.class)//指定在哪里出现的异常会被处理
public R GlobalError(Exception e) {
e.printStackTrace();
return R.error().message("执行全局异常处理");
}
/**
* 优先执行特定异常
* 特定异常处理
*/
@ResponseBody
@ExceptionHandler(ArithmeticException.class)//指定在哪里出现的异常会被处理
public R ArithmeticError(Exception e) {
e.printStackTrace();
return R.error().message("ArithmeticException出现");
}
/**
* 自定义异常
*/
@ExceptionHandler
@ResponseBody
public R error(GuliException e) {
//会把日志信息写到文件中
log.error(e.getMsg());
e.printStackTrace();
return R.error().message(e.getMsg()).code(e.getCode());
}
}
对字段进行填充
package com.atguigu.eduservice.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.nio.channels.NetworkChannel;
import java.util.Date;
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
/**
* 对插入字段进行自动填充->这里就是创建时间和修改时间我们会自动填充
*
* @param metaObject
*/
@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);
}
}
4.控制层例子
package com.atguigu.eduservice.controller;
import com.atguigu.eduservice.R;
import com.atguigu.eduservice.entity.EduTeacher;
import com.atguigu.eduservice.entity.vo.TeacherQuery;
import com.atguigu.eduservice.service.EduTeacherService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
/**
* <p>
* 讲师 前端控制器
* </p>
* http://localhost:8001/eduservice/edu-teacher/findAll
*
* @author testjava
* @since 2022-07-05
*/
@Api(description = "讲师管理")
@RestController
@CrossOrigin
@RequestMapping("/eduservice/teacher")
public class EduTeacherController {
@Autowired
private EduTeacherService teacherService;
/**
* 1.查询教师表中所有数据
* SELECT id,name,intro,career,level,avatar,sort,is_deleted,gmt_create,gmt_modified FROM edu_teacher WHERE is_deleted=0
*/
@ApiOperation(value = "所有讲师")
@GetMapping("findAll")
public R findAllTeacher() {
List<EduTeacher> list = teacherService.list(null);
return R.ok().data("items", list);
}
/**
* 2.逻辑删除讲师的方法:rest风格来一手
*/
@ApiOperation(value = "根据逻辑删除讲师")
@DeleteMapping("{id}")
public R removeTeacher(@PathVariable String id) {
boolean flag = teacherService.removeById(id);
System.out.println("删除成功:" + flag);
//具体判断进行返回
if (flag) {
return R.ok();
} else {
return R.error();
}
}
/**
* 3.分页查询讲师
* SELECT id,name,intro,career,level,avatar,sort,is_deleted,gmt_create,gmt_modified FROM edu_teacher WHERE is_deleted=0 LIMIT 0,3
*/
@GetMapping("pageTeacher/{current}/{limit}")
public R pageListTeacher(@PathVariable long current, @PathVariable long limit) {
//创建page对象
Page<EduTeacher> teacherPage = new Page<>(current, limit);
//调用方法进行分页,会将分页的数据封装到teacherPage里面
teacherService.page(teacherPage, null);
//总记录数
long total = teacherPage.getTotal();
//得到分页后数据集合
List<EduTeacher> records = teacherPage.getRecords();
HashMap map = new HashMap();
map.put("total", total);
map.put("rows", records);
return R.ok().data(map);
}
/**
* 4.多条件组合查询
* 讲师级别,入住时间,名称...
* 多条件:我们可以将条件值传入对象中,然后将对象传递到接口中(vo)
* PageHelper的话调用startPage然后封装到PageInfo下即可
* 这里的TeacherQuery也可以用@RequestBody来传递数据->Post提交
* 传递的为Json数据,将Json数据封装到对象里面
* 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 */
@PostMapping("pageTeacherCondition/{current}/{limit}")
public R pageTeacherCondition(@PathVariable long current, @PathVariable long limit, @RequestBody(required = false) TeacherQuery teacherQuery) {
//创建Page对象
Page<EduTeacher> teacherPage = new Page<>(current, limit);
//wrapper构建条件过滤
QueryWrapper<EduTeacher> wrapper = new QueryWrapper<>();
String name = teacherQuery.getName();
Integer level = teacherQuery.getLevel();
String begin = teacherQuery.getBegin();
String end = teacherQuery.getEnd();
wrapper.like(StringUtils.isNotBlank(name), "name", name)
.like(level != null, "level", level)
.ge(begin != null, "gmt_create", begin)
.le(end != null, "gmt_create", end);
//按照时间降序处理
wrapper.orderByDesc("gmt_create");
//对过滤条件进行封装进而->得到分页数据
teacherService.page(teacherPage, wrapper);
long total = teacherPage.getTotal();
List<EduTeacher> records = teacherPage.getRecords();
return R.ok().data("total", total).data("rows", records);
}
/**
*5.添加讲师
*/
@ApiOperation(value = "添加讲师")
@PostMapping("addTeacher")
public R addTeacher(@RequestBody EduTeacher eduTeacher){
boolean save = teacherService.save(eduTeacher);
return save?R.ok():R.error();
}
/**
* 6.修改讲师
* 根据讲师id先进行查询,然后修改
* UPDATE edu_teacher SET name=?, intro=?, career=?, level=?, avatar=?, sort=?, gmt_modified=? WHERE id=? AND is_deleted=0
*/
@GetMapping("getTeacher/{id}")
public R getTeacher(@PathVariable String id){
EduTeacher eduTeacher = teacherService.getById(id);
return R.ok().data("teacher",eduTeacher);
}
@ApiOperation(value = "修改讲师")
@PostMapping("updateTeacher")
public R updateTeacher(@RequestBody EduTeacher eduTeacher){
boolean flag = teacherService.updateById(eduTeacher);
if(flag){
return R.ok();
}else{
return R.error();
}
}
}
返回我们的json数据
5.来看前端
5.1在我们的config下配置了路由信息dev.env.js
9001是我们nginx负载均衡的端口
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
// BASE_API: '"https://easy-mock.com/mock/5950a2419adc231f356a6636/vue-admin"',
BASE_API: '"http://localhost:9001"',
})
5.2定义我们的后台api
里面调用了我们后台的接口
import request from '@/utils/request'
export default {
//1.讲师列表(条件查询分页)
//参数分别为当前页,每页记录数,
getTeacherListPage(current,limit,teacherQuery) {
return request({
url: `/eduservice/teacher/pageTeacherCondition/${current}/${limit}`,
method: 'post',
//teacherQuery条件对象,后端使用RequestBody传输数据
//data表示对象传唤成json传输
data: teacherQuery
})
},
deleteTeacherId(id){
return request({
url: `/eduservice/teacher/${id}`,
method: 'delete'
//teacherQuery条件对象,后端使用RequestBody传输数据
//data表示对象传唤成json传输
// data: teacherQuery
})
},
addTeacher(teacher){
return request({
url: '/eduservice/teacher/addTeacher',
method: 'post',
//将teacher转为json传输数据
data: teacher
})
},
getTeacherInfo(id){
return request({
url: `/eduservice/teacher/getTeacher/${id}`,
method: 'get'
})
},
//修改讲师
updateTeacherInfo(teacher){
return request({
url: `/eduservice/teacher/updateTeacher`,
method: 'post',
data: teacher
})
},
//2.查询所有的讲师
getListTeacher(){
return request({
url: `/eduservice/teacher/findAll`,
method: 'get'
})
}
}
5.3然后再在具体页面调用封装后台接口的js文件,调用里面的方法
<script>
//引入teacher.js文件
import teacher from '@/api/edu/teacher'
export default{
//核心代码位置
data(){//定义变量和初始值
return {
list:null,//查询后的接口返回值
page:1,
limit:10,
total:0,//总记录数
teacherQuery:{
}//条件封装的对象
}
},
created(){//页面渲染前,调用methods定义的方法
//调用
this.getList()
},
methods:{ //创建具体的方法
//讲师列表的方法
getList(page=1) {
this.page=page
teacher.getTeacherListPage(this.page,this.limit,this.teacherQuery)
.then(response=>{//请求成功
//response返回接口数据
// console.log(response)
this.list=response.data.rows
this.total=response.data.total
console.log(this.list)
console.log(this.total)
})
.catch(error=>{
console.log(error)
}) //失败
},
resetData(){//清空的方法
//表单输入数据清空
this.teacherQuery={}
//查询所有讲师的数据
this.getList()
},
//删除讲师的方法
removeDataById(id) {
// debugger
// console.log(memberId)
this.$confirm('此操作将永久删除该记录, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {//点击确定,删除then方法
teacher.deleteTeacherId(id)
.then(response => {//删除成功
//提示信息
this.$message({
type: 'success',
message: '删除成功!'
});
//回到列表页面
this.getList()
})
// 点击取消
})
}
}
}
6.nginx中的配置
监听9001端口根据名称进行路由
server {
listen 9001;
server_name localhost;
location ~ /eduservice/ {
proxy_pass http://localhost:8001;
}
location ~ /eduoss/ {
proxy_pass http://localhost:8002;
}
location ~ /eduvod/ {
proxy_pass http://localhost:8003;
}
location ~ /educms/ {
proxy_pass http://localhost:8004;
}
location ~ /educenter/ {
proxy_pass http://localhost:8006;
}
location ~ /edumsm/ {
proxy_pass http://localhost:8005;
}
}