宜城网站开发,中山专业门户网站制作策划,网店模板图片,wap什么意思目录
一、登录功能
1.1 思路
1.2 LoginController
1.3 EmpService
1.4 EmpServiceImpl
1.5 EmpMapper
1.6 启动服务-测试
1.7 前后端联调
二、登录校验#xff08;重点#xff09;
2.1 问题 2.2 问题分析 2.3 登录校验编辑
2.4 会话技术
2.4.1 会话技术 2.4.2 …目录
一、登录功能
1.1 思路
1.2 LoginController
1.3 EmpService
1.4 EmpServiceImpl
1.5 EmpMapper
1.6 启动服务-测试
1.7 前后端联调
二、登录校验重点
2.1 问题 2.2 问题分析 2.3 登录校验编辑
2.4 会话技术
2.4.1 会话技术 2.4.2 会话跟踪方案对比
2.5 JWT令牌
2.5.1 简介
2.5.2 应用场景
2.5.3 jwt-生成
5.5.3.1 引入包
5.5.3.2 生成JWT 5.5.3.3 解析JWT
2.6 案例实现JWT 2.6.1 新建JwtUtils工具类
2.6.2 LoginController
2.6.3 启动服务-测试
2.6.4 前后端联调
2.7 过滤器Filter
2.7.1 概述
2.7.2 快速入门 2.7.2.1 新增DemoFilter 2.7.2.2 SpringBootProjectTestApplication
2.7.2.3 启动服务-测试
2.7.2.4 总结
2.7.3 详解执行流程、拦截路径、过滤器链
2.7.3.1 执行流程 2.7.3.2 Filter-拦截路径 编辑
2.7.3.3 过滤器链优先级按过滤器名自然排序 2.7.3.4 总结
2.7.4 案例-登录校验-Filter
2.7.4.1 思路 2.7.4.2 pom.xml引入依赖fastjson
2.7.4.3 新建工具类拦截器LoginCheckFilter 2.7.4.4 启动服务-测试
2.8 拦截器Interceptor
2.8.1 简介
2.8.2 快速入门
2.8.2.1 新建LoginCheckInterceptor 2.8.2.2 WebConfig
2.8.2.3 启动服务测试
2.8.3 详解
2.8.3.1 拦截路径
2.8.3.2 拦截器- 执行流程
2.8.4 案例-登录校验-Interceptor
2.8.4.1 LoginCheckInterceptor
2.8.4.2 WebConfig
2.8.4.3 启动服务-测试
三、异常处理
3.1 异常现象--新增重复名称部门
3.2 思考如何处理 3.3 全家异常处理 3.3.1 异常类GlobalExceptionHandler
3.3.2 启动服务-测试 3.3.3 总结 前言实现案例的登录功能、登录校验和异常处理 一、登录功能
1.1 思路 1.2 LoginController package com.runa.controller;import com.runa.pojo.Emp;
import com.runa.pojo.Result;
import com.runa.service.EmpService;
import lombok.extern.slf4j.Slf4j;
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.RestController;Slf4j
RestController
public class LoginController {Autowiredprivate EmpService empService;PostMapping(/login)public Result login(RequestBody Emp emp){log.info(登录的用户{},emp);Emp e empService.login(emp);return e ! null ? Result.success():Result.error(用户名或密码错误);}
}1.3 EmpService
package com.runa.service;import com.runa.pojo.Emp;
import com.runa.pojo.PageBean;
import org.springframework.format.annotation.DateTimeFormat;import java.time.LocalDate;
import java.util.List;public interface EmpService {/*** 分页查询 不带条件* param page* param pageSize* return*/
// PageBean page(Integer page, Integer pageSize);/*** 分页查询 带条件* param page* param pageSize* return*/PageBean page(Integer page, Integer pageSize,String name, Short gender, LocalDate begin, LocalDate end);/*** 批量删除员工* param ids*/void delete(ListInteger ids);/*** 新增员工* param emp*/void save(Emp emp);/*** 根据id查询员工* param id* return*/Emp getById(Integer id);/*** 修改员工* param emp*/void update(Emp emp);/*** 登录* param emp* return*/Emp login(Emp emp);
}1.4 EmpServiceImpl
package com.runa.service.impl;import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.runa.mapper.EmpMapper;
import com.runa.pojo.Emp;
import com.runa.pojo.PageBean;
import com.runa.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;Service
public class EmpServiceImpl implements EmpService {Autowiredprivate EmpMapper empMapper;/*** 分页查询 pagehelper组合查询* param page* param pageSize* param name* param gender* param begin* param end* return*/Overridepublic PageBean page(Integer page, Integer pageSize, String name, Short gender, LocalDate begin, LocalDate end) {// 1 设置分页参数PageHelper.startPage(page, pageSize);// 2 执行查询ListEmp empList empMapper.list(name, gender, begin, end);PageEmp p (PageEmp) empList;// 3 封装PangeBean对象PageBean pageBean new PageBean(p.getTotal(),((PageEmp) empList).getResult());return pageBean;}/*** 批量删除员工* param ids*/Overridepublic void delete(ListInteger ids) {empMapper.delete(ids);}/*** 新增员工* param emp*/Overridepublic void save(Emp emp) {emp.setCreateTime(LocalDateTime.now());emp.setUpdateTime(LocalDateTime.now());empMapper.insert(emp);}/*** 根据ID查询员工* param id* return*/Overridepublic Emp getById(Integer id) {return empMapper.getByID(id);}/*** 修改员工* param emp*/Overridepublic void update(Emp emp) {emp.setUpdateTime(LocalDateTime.now());empMapper.update(emp);}/*** 登录* param emp* return*/Overridepublic Emp login(Emp emp) {return empMapper.getByUsernameAndPassword(emp);}/*** 分页查询 加pagehelper* param page* param pageSize* return*/
// Override
// public PageBean page(Integer page, Integer pageSize) {
// // 1 设置分页参数
// PageHelper.startPage(page, pageSize);
//
// // 2 执行查询
// ListEmp empList empMapper.list();
// PageEmp p (PageEmp) empList;
//
// // 3 封装PangeBean对象
// PageBean pageBean new PageBean(p.getTotal(),((PageEmp) empList).getResult());
// return pageBean;
// }/*** 分页查询* param page* param pageSize* return*/
// Override
// public PageBean page(Integer page, Integer pageSize) {
// // 1 获取总记录数
// Long count empMapper.count();
//
// // 2 获取分页查询结果列表
// Integer start (page - 1) * pageSize;
// ListEmp empList empMapper.page(start, pageSize);
//
// // 3 封装PangeBean对象
// PageBean pageBean new PageBean(count,empList);
// }}1.5 EmpMapper
package com.runa.mapper;import com.runa.pojo.Emp;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;import java.time.LocalDate;
import java.util.List;/*** 员工管理*/
Mapper
public interface EmpMapper {/*** 查询总记录数* return*/
// Select(select count(*) from emp)
// public Long count();/*** 分页查询 获取列表数据* param start* param pageSize* return*/
// Select(select * from emp limit #{start}, #{pageSize})
// public ListEmp page(Integer start, Integer pageSize);/*** 使用pagehelper的员工信息查询* return*/
// Select(select * from emp)
// public ListEmp list();/*** 使用pagehelper的员工信息查询(带条件)--动态sql* 使用xml注解sql* return*/public ListEmp list(String name, Short gender, LocalDate begin, LocalDate end);/*** 批量删除员工* param ids*/void delete(ListInteger ids);/*** 新增员工* param emp*/Insert(insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time) values(#{username}, #{name}, #{gender}, #{image}, #{job}, #{entrydate}, #{deptId}, #{createTime}, #{updateTime}))void insert(Emp emp);/*** 根据id查询员工* param id* return*/Select(select * from emp where id #{id})Emp getByID(Integer id);/*** 修改员工* param emp*/void update(Emp emp);/*** 登录* param emp* return*/Select(select * from emp where username #{username} and password #{password})Emp getByUsernameAndPassword(Emp emp);
}1.6 启动服务-测试 1.7 前后端联调 二、登录校验重点
2.1 问题 2.2 问题分析 2.3 登录校验
2.4 会话技术
2.4.1 会话技术 2.4.2 会话跟踪方案对比 Cookies与Session例子启动服务http://localhost:8080/c1 package com.runa.controller;import com.runa.pojo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;/*** HttpSession演示*/
Slf4j
RestController
public class SessionController {//设置CookieGetMapping(/c1)public Result cookie1(HttpServletResponse response){response.addCookie(new Cookie(login_username,itheima)); //设置Cookie/响应Cookiereturn Result.success();}//获取CookieGetMapping(/c2)public Result cookie2(HttpServletRequest request){Cookie[] cookies request.getCookies();for (Cookie cookie : cookies) {if(cookie.getName().equals(login_username)){System.out.println(login_username: cookie.getValue()); //输出name为login_username的cookie}}return Result.success();}GetMapping(/s1)public Result session1(HttpSession session){log.info(HttpSession-s1: {}, session.hashCode());session.setAttribute(loginUser, tom); //往session中存储数据return Result.success();}GetMapping(/s2)public Result session2(HttpServletRequest request){HttpSession session request.getSession();log.info(HttpSession-s2: {}, session.hashCode());Object loginUser session.getAttribute(loginUser); //从session中获取数据log.info(loginUser: {}, loginUser);return Result.success(loginUser);}
}2.5 JWT令牌
2.5.1 简介 2.5.2 应用场景 2.5.3 jwt-生成 5.5.3.1 引入包 !--JWT令牌--dependencygroupIdio.jsonwebtoken/groupIdartifactIdjjwt/artifactIdversion0.9.1/version/dependency
5.5.3.2 生成JWT 记得注释他//SpringBootTest
package com.runa;import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;import java.util.Date;
import java.util.HashMap;
import java.util.Map;//SpringBootTest
class SpringBootProjectTestApplicationTests {// Test
// void contextLoads() {
// }/*** 测试JWT令牌的生成*/Testpublic void testGenJwt(){MapString, Object claims new HashMap();claims.put(id,1);claims.put(name,bocai);String jwt Jwts.builder().signWith(SignatureAlgorithm.HS256, runa) // 签名算法 算法有哪些上官网.setClaims(claims) //自定义的内容载荷.setExpiration(new Date(System.currentTimeMillis() 3600* 1000)) // 设置有效期为1h.compact();System.out.println(jwt);}}生成的jwt令牌上官网 5.5.3.3 解析JWT
package com.runa;import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;import java.util.Date;
import java.util.HashMap;
import java.util.Map;//SpringBootTest
class SpringBootProjectTestApplicationTests {// Test
// void contextLoads() {
// }/*** 生成Jwt令牌*/Testpublic void testGenJwt(){MapString, Object claims new HashMap();claims.put(id,1);claims.put(name,bocai);String jwt Jwts.builder().signWith(SignatureAlgorithm.HS256, runa) // 签名算法 算法有哪些上官网.setClaims(claims) //自定义的内容载荷.setExpiration(new Date(System.currentTimeMillis() 3600* 1000)) // 设置有效期为1h.compact();System.out.println(jwt);}/*** 解析Jwt*/Testpublic void testPareJwt(){Claims claims Jwts.parser().setSigningKey(runa) //runa要与前面生成一致.parseClaimsJws(eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiYm9jYWkiLCJpZCI6MSwiZXhwIjoxNjkyNzc3MzAwfQ.KPqgKc5JS8j7GN7aPQ0GwQnUaGm78WWbzf2N7LGq34g).getBody();System.out.println(claims);}}2.6 案例实现JWT 2.6.1 新建JwtUtils工具类 package com.runa.utils;import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
import java.util.Map;public class JwtUtils {private static String signKey runa;private static Long expire 43200000L; // 12h/*** 生成JWT令牌* param claims JWT第二部分负载 payload 中存储的内容* return*/public static String generateJwt(MapString, Object claims){String jwt Jwts.builder().addClaims(claims).signWith(SignatureAlgorithm.HS256, signKey).setExpiration(new Date(System.currentTimeMillis() expire)).compact();return jwt;}/*** 解析JWT令牌* param jwt JWT令牌* return JWT第二部分负载 payload 中存储的内容*/public static Claims parseJWT(String jwt){Claims claims Jwts.parser().setSigningKey(signKey).parseClaimsJws(jwt).getBody();return claims;}
}2.6.2 LoginController
package com.runa.controller;import com.runa.pojo.Emp;
import com.runa.pojo.Result;
import com.runa.service.EmpService;
import com.runa.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
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.RestController;import java.util.HashMap;
import java.util.Map;Slf4j
RestController
public class LoginController {Autowiredprivate EmpService empService;PostMapping(/login)public Result login(RequestBody Emp emp){log.info(登录的用户{},emp);Emp e empService.login(emp);// 登录成功生成令牌下发令牌if(e ! null){MapString, Object claims new HashMap();claims.put(id,e.getId());claims.put(name, e.getName());claims.put(username, e.getUsername());String jwt JwtUtils.generateJwt(claims);return Result.success(jwt);}// 登录失败返回错误信息return Result.error(用户名或密码错误);}
}2.6.3 启动服务-测试 2.6.4 前后端联调 2.7 过滤器Filter
2.7.1 概述 2.7.2 快速入门 2.7.2.1 新增DemoFilter package com.runa.filter;import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;import java.io.IOException;WebFilter(urlPatterns /*)
public class DemoFilter implements Filter {Override // 初始化方法只调用一次public void init(FilterConfig filterConfig) throws ServletException {System.out.println(init初始化方法执行了);}Override // 拦截到请求之后调用调用多次public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println(拦截到请求了~~~);// 放行filterChain.doFilter(servletRequest,servletResponse);}Override // 销毁方法只调用一次public void destroy() {System.out.println(destroy方法执行了);}
}2.7.2.2 SpringBootProjectTestApplication
package com.runa;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;ServletComponentScan //开启了对servlet组件支持
SpringBootApplication
public class SpringBootProjectTestApplication {public static void main(String[] args) {SpringApplication.run(SpringBootProjectTestApplication.class, args);}}2.7.2.3 启动服务-测试
略
2.7.2.4 总结 2.7.3 详解执行流程、拦截路径、过滤器链
2.7.3.1 执行流程 2.7.3.2 Filter-拦截路径
2.7.3.3 过滤器链优先级按过滤器名自然排序 package com.runa.filter;import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;import java.io.IOException;WebFilter(urlPatterns /*)
public class SecondFilter implements Filter {Override // 拦截到请求之后调用调用多次public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println(SecondFilter 拦截---2到请求了~~~放行之前逻辑);// 放行filterChain.doFilter(servletRequest,servletResponse);System.out.println(SecondFilter拦截---2到请求了~~~放行之后逻辑);}
}2.7.3.4 总结 2.7.4 案例-登录校验-Filter 2.7.4.1 思路 2.7.4.2 pom.xml引入依赖fastjson !--fastJSON--dependencygroupIdcom.alibaba/groupIdartifactIdfastjson/artifactIdversion1.2.76/version/dependency
2.7.4.3 新建工具类拦截器LoginCheckFilter
package com.runa.filter;import com.alibaba.fastjson.JSONObject;
import com.runa.pojo.Result;
import com.runa.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;Slf4j
//WebFilter(urlPatterns /*)
public class LoginCheckFilter implements Filter {Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {HttpServletRequest req (HttpServletRequest) request;HttpServletResponse resp (HttpServletResponse) response;//1.获取请求url。String url req.getRequestURL().toString();log.info(请求的url: {},url);//2.判断请求url中是否包含login如果包含说明是登录操作放行。if(url.contains(login)){log.info(登录操作, 放行...);chain.doFilter(request,response);return;}//3.获取请求头中的令牌token。String jwt req.getHeader(token);//4.判断令牌是否存在如果不存在返回错误结果未登录。if(!StringUtils.hasLength(jwt)){log.info(请求头token为空,返回未登录的信息);Result error Result.error(NOT_LOGIN);//手动转换 对象--json -------- 阿里巴巴fastJSONString notLogin JSONObject.toJSONString(error);resp.getWriter().write(notLogin);return;}//5.解析token如果解析失败返回错误结果未登录。try {JwtUtils.parseJWT(jwt);} catch (Exception e) {//jwt解析失败e.printStackTrace();log.info(解析令牌失败, 返回未登录错误信息);Result error Result.error(NOT_LOGIN);//手动转换 对象--json -------- 阿里巴巴fastJSONString notLogin JSONObject.toJSONString(error);resp.getWriter().write(notLogin);return;}//6.放行。log.info(令牌合法, 放行);chain.doFilter(request, response);}
}2.7.4.4 启动服务-测试
记得将 DemoFilter 与SecondFilter 的WebFilter(urlPatterns /*) 注释掉 2.8 拦截器Interceptor
2.8.1 简介 2.8.2 快速入门 2.8.2.1 新建LoginCheckInterceptor package com.runa.interceptor;import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;Component
public class LoginCheckInterceptor implements HandlerInterceptor {Override //目标资源方法运行前运行, 返回true: 放行, 放回false, 不放行public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {System.out.println(preHandle ...);return true;}Override //目标资源方法运行后运行public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println(postHandle ...);}Override //视图渲染完毕后运行, 最后运行public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println(afterCompletion...);}
}2.8.2.2 WebConfig package com.runa.config;import com.runa.interceptor.LoginCheckInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;Configuration //配置类
public class WebConfig implements WebMvcConfigurer {Autowiredprivate LoginCheckInterceptor loginCheckInterceptor;Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginCheckInterceptor).addPathPatterns(/**);}
}2.8.2.3 启动服务测试 将过滤器 LoginCheckFilter WebFilter(urlPatterns /*) 注释掉 2.8.3 详解
2.8.3.1 拦截路径 2.8.3.2 拦截器- 执行流程 2.8.4 案例-登录校验-Interceptor
2.8.4.1 LoginCheckInterceptor
package com.runa.interceptor;import com.alibaba.fastjson.JSONObject;
import com.runa.pojo.Result;
import com.runa.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;Slf4j
Component
public class LoginCheckInterceptor implements HandlerInterceptor {Override //目标资源方法运行前运行, 返回true: 放行, 放回false, 不放行public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {//1.获取请求url。String url req.getRequestURL().toString();log.info(请求的url: {},url);//2.判断请求url中是否包含login如果包含说明是登录操作放行。if(url.contains(login)){log.info(登录操作, 放行...);return true;}//3.获取请求头中的令牌token。String jwt req.getHeader(token);//4.判断令牌是否存在如果不存在返回错误结果未登录。if(!StringUtils.hasLength(jwt)){log.info(请求头token为空,返回未登录的信息);Result error Result.error(NOT_LOGIN);//手动转换 对象--json -------- 阿里巴巴fastJSONString notLogin JSONObject.toJSONString(error);resp.getWriter().write(notLogin);return false;}//5.解析token如果解析失败返回错误结果未登录。try {JwtUtils.parseJWT(jwt);} catch (Exception e) {//jwt解析失败e.printStackTrace();log.info(解析令牌失败, 返回未登录错误信息);Result error Result.error(NOT_LOGIN);//手动转换 对象--json -------- 阿里巴巴fastJSONString notLogin JSONObject.toJSONString(error);resp.getWriter().write(notLogin);return false;}//6.放行。log.info(令牌合法, 放行);return true;}Override //目标资源方法运行后运行public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println(postHandle ...);}Override //视图渲染完毕后运行, 最后运行public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println(afterCompletion...);}
}2.8.4.2 WebConfig
package com.runa.config;import com.runa.interceptor.LoginCheckInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;Configuration //配置类
public class WebConfig implements WebMvcConfigurer {Autowiredprivate LoginCheckInterceptor loginCheckInterceptor;Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginCheckInterceptor).addPathPatterns(/**).excludePathPatterns(/login);}
}2.8.4.3 启动服务-测试
注释Filter 三、异常处理
3.1 异常现象--新增重复名称部门 3.2 思考如何处理 3.3 全家异常处理 3.3.1 异常类GlobalExceptionHandler package com.runa.exception;import com.runa.pojo.Result;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;/*** 全局异常处理器*/
RestControllerAdvice
public class GlobalExceptionHandler {ExceptionHandler(Exception.class)//捕获所有异常public Result ex(Exception ex){ex.printStackTrace();return Result.error(对不起,操作失败,请联系管理员);}}3.3.2 启动服务-测试
新建重复部门 3.3.3 总结