SpringBoot后端:从分页查询到登录校验
分页查询GetMapping() public Result list(Integer page, Integer pagesize){ log.info(分页查询page:{} pagesize{}, page, pagesize); PageEmpEmp result empService.findAll(page,pagesize); return Result.success(result); }Override public PageEmpEmp findAll(Integer page, Integer pagesize) { int start(page-1)*pagesize; long totaldeptMapper.count(); ListEmp datadeptMapper.findAll(start,pagesize); return new PageEmp(total,data); } Mapper public interface EmpMapper { Select(select * from emp e left join dept d on e.dept_id d.id limit #{start},#{pagesize}) ListEmp findAll(int start, Integer pagesize); Select(select count(*) from emp e left join dept d on e.dept_id d.id ) long count(); }PageHelper简单分页查询Mapper public interface EmpMapper { Select(select * from emp e left join dept d on e.dept_id d.id ) ListEmp findAll(); } Service public class EmpServiceImpl implements EmpService { Autowired private EmpMapper empMapper; Override public PageEmpEmp findAll(Integer page, Integer pagesize) { PageHelper.startPage(page,pagesize); ListEmp empList empMapper.findAll(); PageEmp p (PageEmp) empList; return new PageEmp(p.getTotal(),p.getResult()); } }条件分页查询GetMapping() public Result list(RequestParam(defaultValue 1)Integer page, RequestParam(defaultValue 10)Integer pageSize, Integer id, String name, DateTimeFormat(pattern yyyy-MM-dd) LocalDate begin, DateTimeFormat(pattern yyyy-MM-dd) LocalDate end) { log.info(分页查询{},{},{},{},{},{}, page, pageSize,id,name,begin,end); PageEmpEmp result empService.findAll(page,pageSize,id,name,begin,end); return Result.success(result); }public PageEmpEmp findAll(Integer page, Integer pageSize, Integer id, String name, LocalDate begin, LocalDate end) { PageHelper.startPage(page,pageSize); ListEmp empList empMapper.findAll(id, name, begin, end); PageEmp p (PageEmp) empList; return new PageEmp(p.getTotal(),p.getResult()); }Mapper public interface EmpMapper { ListEmp findAll(Integer id, String name, LocalDate begin, LocalDate end); }?xml version1.0 encodingUTF-8 ? !DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespacecom.itwyz.demo2.mapper.EmpMapper select idfindAll resultTypecom.itwyz.demo2.pojo.Emp select e.* from emp e left join dept d on e.dept_idd.id where if testname!null and name! e.name like concat(%,#{name},%) /if if testid!null and e.id#{id} /if if testbegin!null and e.create_time gt; #{begin} /if /select /mapper 条件查询优化public class EmpQueryParam { private Integer page1; private Integer pageSize10; private String name; private Integer age; private LocalDateTime createTime; private LocalDateTime updateTime; private String deptName; }GetMapping() public Result list(EmpQueryParam empQueryParam) { log.info(分页查询{}, empQueryParam); PageEmpEmp result empService.findAll(empQueryParam); return Result.success(result); }Override public PageEmpEmp findAll(EmpQueryParam empQueryParam) { PageHelper.startPage(empQueryParam.getPage(),empQueryParam.getPageSize()); ListEmp empList empMapper.findAll(empQueryParam); PageEmp p (PageEmp) empList; return new PageEmp(p.getTotal(),p.getResult()); }Mapper public interface EmpMapper { ListEmp findAll(EmpQueryParam empQueryParam); } ?xml version1.0 encodingUTF-8 ? !DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespacecom.itwyz.demo2.mapper.EmpMapper select idfindAll resultTypecom.itwyz.demo2.pojo.Emp select e.* from emp e left join dept d on e.dept_idd.id where if testname!null and name! e.name like concat(%,#{name},%) /if if testage!null and e.age#{age} /if if testcreateTime!null and e.create_time #{createTime} /if if testupdateTime!null and e.create_time #{updateTime} /if /select /mapper 新增批量保存PostMapping() public Result add(RequestBody Emp emp) { log.info(新增员工{}, emp); empService.save(emp); return Result.success(); }public void save(Emp emp) { //1.保存员工基本信息 emp.setCreateTime(LocalDateTime.now()); emp.setUpdateTime(LocalDateTime.now()); empMapper.insert(emp); ListExpr exprList emp.getExprList(); if(!exprList.isEmpty()){ exprList.forEach(expr-{ expr.setEmpId(emp.getId()); }); } empMapper.insertBach(exprList); }Options(useGeneratedKeys true,keyProperty id)//获取到生成的主键 Insert(insert into emp(name,age,dept_id,create_time,update_time) values(#{name},#{age},#{deptId},#{createTime},#{updateTime})) void insert(Emp emp); void insertBach(ListExpr exprList);mapper namespacecom.itwyz.demo2.mapper.EmpMapper insert idinsertBach insert into expr (emp_id,expr) values foreach collectionexprList itemexpr separator, (#{expr.empId},#{expr.expr}) /foreach /insert不用xml映射文件PostMapping() public Result add(RequestBody Emp emp) { log.info(新增员工{}, emp); empService.save(emp); return Result.success(); }public void save(Emp emp) { //1.保存员工基本信息 emp.setCreateTime(LocalDateTime.now()); emp.setUpdateTime(LocalDateTime.now()); empMapper.insert(emp); //2.保存员工的工作信息 emp.getExprList().forEach(expr-{ expr.setEmpId(emp.getId()); empMapper.insertbach(expr); }); }Options(useGeneratedKeys true,keyProperty id)//获取到生成的主键 Insert(insert into emp(name,age,dept_id,create_time,update_time) values(#{name},#{age},#{deptId},#{createTime},#{updateTime})) void insert(Emp emp); Insert(insert into expr(emp_id,expr) values(#{empId},#{expr})) void insertbach(Expr expr);事务事务是一组操作的集合它是一个不可分割的单位。这些操作要么同时成功要么同时失败。开启start transaction提交commit回滚rollbackREQUIRED(默认)REQUIRED_NEW需要在一个新事务中运行文件上传本地存储!DOCTYPE html html langen head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title文件上传/title /head body form action/upload methodpost enctypemultipart/form-data 姓名input typetext namenamebr 年龄input typetext nameagebr 头像input typefile namefilebr input typesubmit value提交 /form /body /htmlPostMapping(/upload) public Result upload(String name,Integer age,MultipartFile file) throws IOException { log.info(接受参数:{}{}{},name,age,file); String originalFilename file.getOriginalFilename(); String suffix originalFilename.substring(originalFilename.lastIndexOf(.)); String newName UUID.randomUUID() suffix; file.transferTo(new File(D:\\Code\\JAVA\\Web\\demo2\\src\\main\\File\\newName)); return Result.success(); }阿里云OSS阿里云对象存储OSS是一款海量、安全、低成本、高可靠的云存储服务。使用OSS可以通过网络存储和调用包括文本、图片、音频和视频在内的各种文件。创建创建Bucket填入Buket名称其它都不用动关闭阻止公共访问设置公共读创建Accesskey配置AccessKeyset OSS_ACCESS_KEY_IDYOUR_ACCESS_KEY_ID set OSS_ACCESS_KEY_SECRETYOUR_ACCESS_KEY_SECRET让更改生效setx OSS_ACCESS_KEY_ID %OSS_ACCESS_KEY_ID% setx OSS_ACCESS_KEY_SECRET %OSS_ACCESS_KEY_SECRET%验证环境变量是否生效echo %OSS_ACCESS_KEY_ID% echo %OSS_ACCESS_KEY_SECRET%案例磁盘存储package com.itwyz.demo2.controller; import java.io.*; import java.nio.file.Files; import java.util.Random; import com.aliyun.oss.*; import com.aliyun.oss.common.auth.CredentialsProviderFactory; import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider; import com.aliyun.oss.model.OSSObject; import com.aliyun.oss.model.ObjectListing; import com.aliyun.oss.model.OSSObjectSummary; import com.aliyun.oss.common.comm.SignVersion; public class OssJavaSdkQuickStart { public static void main(String[] args) throws com.aliyuncs.exceptions.ClientException { // 设置 OSS Endpoint 和 Bucket 名称 String endpoint https://oss-cn-beijing.aliyuncs.com; String bucketName web52; String objectName 001.jpg; // 替换为您的 Bucket 区域 String region cn-beijing; // 从环境变量中获取访问凭证。运行本代码示例之前请先配置环境变量 EnvironmentVariableCredentialsProvider credentialsProvider CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 创建 OSSClient 实例 ClientBuilderConfiguration clientBuilderConfiguration new ClientBuilderConfiguration(); // 显式声明使用 V4 签名算法 clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); OSS ossClient OSSClientBuilder.create() .endpoint(endpoint) .credentialsProvider(credentialsProvider) .region(region) .build(); try { // 1. 创建存储空间Bucket ossClient.createBucket(bucketName); System.out.println(1. Bucket bucketName 创建成功。); // 2. 上传文件 File filenew File(C:\\Users\\86131\\Pictures\\Screenshots\\屏幕截图 2025-04-15 163125.png); byte[] content Files.readAllBytes(file.toPath()); ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content)); System.out.println(2. 文件 objectName 上传成功。); } catch (OSSException oe) { System.out.println(Caught an OSSException, which means your request made it to OSS, but was rejected with an error response for some reason.); System.out.println(Error Message: oe.getErrorMessage()); System.out.println(Error Code: oe.getErrorCode()); System.out.println(Request ID: oe.getRequestId()); System.out.println(Host ID: oe.getHostId()); } catch (ClientException | IOException ce) { System.out.println(Caught an ClientException, which means the client encountered a serious internal problem while trying to communicate with OSS, such as not being able to access the network.); System.out.println(Error Message: ce.getMessage()); } finally { if (ossClient ! null) { ossClient.shutdown(); } } } }上传阿里云存储package com.itwyz.demo2.utils; import java.io.*; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.UUID; import com.aliyun.oss.*; import com.aliyun.oss.common.auth.CredentialsProviderFactory; import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider; import com.aliyun.oss.common.comm.SignVersion; import org.springframework.stereotype.Component; Component public class AliyunOSSOperator { public String upload(byte[]content,String originalFilename) throws com.aliyuncs.exceptions.ClientException { // 设置 OSS Endpoint 和 Bucket 名称 String endpoint https://oss-cn-beijing.aliyuncs.com; String bucketName web-52; // 替换为您的 Bucket 区域 String region cn-beijing; // 获取当前系统日期的字符串格式为 yyyy/MM String dir LocalDate.now().format(DateTimeFormatter.ofPattern(yyyy/MM)); // 生成一个不重复的文件名 String newFileName UUID.randomUUID().originalFilename.substring(originalFilename.lastIndexOf(.)); String objectNamedir/newFileName; // 从环境变量中获取访问凭证。运行本代码示例之前请先配置环境变量 EnvironmentVariableCredentialsProvider credentialsProvider CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 创建 OSSClient 实例 ClientBuilderConfiguration clientBuilderConfiguration new ClientBuilderConfiguration(); // 显式声明使用 V4 签名算法 clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); OSS ossClient OSSClientBuilder.create() .endpoint(endpoint) .credentialsProvider(credentialsProvider) .region(region) .build(); try { // 1. 创建存储空间Bucket ossClient.createBucket(bucketName); System.out.println(1. Bucket bucketName 创建成功。); // 2. 上传文件 ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content)); System.out.println(2. 文件 objectName 上传成功。); } catch (OSSException oe) { System.out.println(Caught an OSSException, which means your request made it to OSS, but was rejected with an error response for some reason.); System.out.println(Error Message: oe.getErrorMessage()); System.out.println(Error Code: oe.getErrorCode()); System.out.println(Request ID: oe.getRequestId()); System.out.println(Host ID: oe.getHostId()); } catch (ClientException ce) { System.out.println(Caught an ClientException, which means the client encountered a serious internal problem while trying to communicate with OSS, such as not being able to access the network.); System.out.println(Error Message: ce.getMessage()); } finally { if (ossClient ! null) { ossClient.shutdown(); } } return endpoint.split(//)[0]//bucketName.endpoint.split(//)[1]/objectName; } }Autowired private AliyunOSSOperator aliyunOSSOperator; PostMapping(/upload2) public Result upload(MultipartFile file) throws Exception{ log.info(文件上传:{},file.getOriginalFilename()); String urlaliyunOSSOperator.upload(file.getBytes(), file.getOriginalFilename()); log.info(文件上传成功:{},url); return Result.success(url); }优化后参数信息从配置文件读取参数配置化指将一些灵活变化的参数配置在配置文件中然后通过Value注解来注入外部配置的属性ValueConfigurationPropertiesData Component ConfigurationProperties(prefix aliyun.oss) public class AliyunOSSProperties { private String endpoint; private String buketName; private String region; }package com.itwyz.demo2.utils; import java.io.*; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.UUID; import com.aliyun.oss.*; import com.aliyun.oss.common.auth.CredentialsProviderFactory; import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider; import com.aliyun.oss.common.comm.SignVersion; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; Component public class AliyunOSSOperator { Autowired private AliyunOSSProperties aliyunOSSProperties; public String upload(byte[]content,String originalFilename) throws com.aliyuncs.exceptions.ClientException { String endpoint aliyunOSSProperties.getEndpoint(); String bucketName aliyunOSSProperties.getBuketName(); String region aliyunOSSProperties.getRegion(); // 获取当前系统日期的字符串格式为 yyyy/MM String dir LocalDate.now().format(DateTimeFormatter.ofPattern(yyyy/MM)); // 生成一个不重复的文件名 String newFileName UUID.randomUUID().originalFilename.substring(originalFilename.lastIndexOf(.)); String objectNamedir/newFileName; // 从环境变量中获取访问凭证。运行本代码示例之前请先配置环境变量 EnvironmentVariableCredentialsProvider credentialsProvider CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 创建 OSSClient 实例 ClientBuilderConfiguration clientBuilderConfiguration new ClientBuilderConfiguration(); // 显式声明使用 V4 签名算法 clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); OSS ossClient OSSClientBuilder.create() .endpoint(endpoint) .credentialsProvider(credentialsProvider) .region(region) .build(); try { // 1. 创建存储空间Bucket ossClient.createBucket(bucketName); System.out.println(1. Bucket bucketName 创建成功。); // 2. 上传文件 ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content)); System.out.println(2. 文件 objectName 上传成功。); } catch (OSSException oe) { System.out.println(Caught an OSSException, which means your request made it to OSS, but was rejected with an error response for some reason.); System.out.println(Error Message: oe.getErrorMessage()); System.out.println(Error Code: oe.getErrorCode()); System.out.println(Request ID: oe.getRequestId()); System.out.println(Host ID: oe.getHostId()); } catch (ClientException ce) { System.out.println(Caught an ClientException, which means the client encountered a serious internal problem while trying to communicate with OSS, such as not being able to access the network.); System.out.println(Error Message: ce.getMessage()); } finally { if (ossClient ! null) { ossClient.shutdown(); } } return endpoint.split(//)[0]//bucketName.endpoint.split(//)[1]/objectName; } }删除逻辑实现PostMapping(/user) public Result addUser(RequestBody User user){ System.out.println(添加用户数据user); userService.addUser(user); return Result.success(); }Transactional(rollbackFor Exception.class) Override public void delete(ListInteger ids) { //删除员工基本信息 empMapper.delete(ids); //删除员工工作信息 empExprMapper.delete(ids); }编辑查询回显resultMap idempResultMap typecom.itwyz.demo2.pojo.Emp id columnid propertyid/ result column name propertyname/ result columnage propertyage/ result columndept_id propertydeptId/ result columncreate_time propertycreateTime/ result columnupdate_time propertyupdateTime/ collection propertyexprList ofTypecom.itwyz.demo2.pojo.Expr result columnemp_id propertyempId/ result columnexpr propertyexpr/ /collection /resultMap select idgetInfo resultMapempResultMap select e.*,ee.emp_id,ee.expr from emp e left join expr ee on e.idee.emp_id where e.id#{id} /select修改PutMapping() public Result update(RequestBody Emp emp){ log.info(修改员工{}, emp); empService.update(emp); return Result.success(); }Transactional(rollbackFor Exception.class) Override public void update(Emp emp) { //1.更新员工基本信息 emp.setUpdateTime(LocalDateTime.now()); empMapper.updateById(emp); //2.更新员工工作信息 empExprMapper.delete(Arrays.asList(emp.getId())); if (!CollectionUtils.isEmpty(emp.getExprList())) { emp.getExprList().forEach(expr-{ expr.setEmpId(emp.getId()); empMapper.insertbach(expr); }); } }update idupdateById update emp set if testname ! null and name ! name #{name}, /if if testage ! null and age ! 0 age #{age}, /if if testdeptId ! null dept_id #{deptId}, /if if testupdateTime ! null update_time #{updateTime} /if /set where id #{id} /update全局异常处理器项目中出现异常例如mapper出现异常异常会由mapper-service-controller然后返回一个JSON格式的Exception响应给前端Slf4j RestControllerAdvice public class GlobalExceptionHandler { ExceptionHandler public Result handleException(Exception e) { log.error(服务器异常:{}, e); return Result.error(服务器异常); } ExceptionHandler public Result handleException(DuplicateKeyException e) { log.error(业务异常:{}, e); String se.getMessage(); int i s.indexOf(Duplicate entry); String errMsgs.substring(i); String[] arrerrMsg.split( ); return Result.error(arr[2]已存在); } }信息统计解决mybatisX误报三种方案删除MybatisX添加MapKey注解如下设置职位统计结合Echarts的柱状图public JobOption getEmpJobData() { ListMapString, Object list empMapper.countEmpJobData(); ListObject jobList list.stream().map(dataMap - dataMap.get(pos)).toList(); ListObject dataList list.stream().map(dataMap - dataMap.get(num)).toList(); return new JobOption(jobList,dataList); }MapKey(pos) ListMapString,Object countEmpJobData();select idcountEmpJobData resultTypejava.util.Map select case dept_id when 1 then 技术部 when 2 then 财务部 when 3 then 人事部 when 4 then 市场部 else 其他 end as pos, count(*) num from emp group by dept_id order by num; /select性别统计登录PostMapping(/login) public Result Login(RequestBody User user){ log.info(登录信息{}, user); LoginInfo info userService.login(user); if(info!null){ return Result.success(info); } return Result.error(用户名或密码错误); }Override public LoginInfo login(User user) { // 根据用户名和密码查询员工信息 User u userMapper.selectByUsernameAndPassword(user.getUsername(),user.getPassword()); //判断是否存在这个员工如果存在组装登录成功信息 if(u!null){ return new LoginInfo(u.getUserId(),u.getUsername(),u.getPassword(),00000); } //不存在返回null return null; }Select(select user_id id,username,password from user where username#{username} and password#{password}) User selectByUsernameAndPassword(String username, String password);登录校验会话Cookie三个自动服务器端创建好cookie后会自动响应给浏览器浏览器会自动将cookie存储在浏览器本地后续请求中cookie会自动携带到浏览器Session底层是基于cookie不同的是cookie中存储的是服务端会话对象session的id值令牌登录成功后创建令牌响应给客户端客户端存储令牌之后每一次请求都携带令牌服务器端校验有效性有效放行无效返回错误结果JWT引入jjwt的依赖dependency groupIdio.jsonwebtoken/groupId artifactIdjjwt/artifactId version0.9.1/version /dependency调用官方提供的工具类Jwts来生成jwt令牌public void testGenerateJwt() { MapString, Object dataMap new HashMap(); dataMap.put(id, 1); dataMap.put(username, wyz); String jwt Jwts.builder().signWith(SignatureAlgorithm.HS256, aXR3eXo) .addClaims(dataMap) .setExpiration(new Date(System.currentTimeMillis() 3600 * 1000)) .compact(); System.out.println(jwt); }public void testParseJwt() { String tokeneyJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJ3eXoiLCJleHAiOjE3NDY1NDU1ODV9.vR9wAR5Q1wQDDDfqTE9NMdB3DwzhZZNqSXRe0BGpCqw; Claims claims Jwts.parser().setSigningKey(aXR3eXo) .parseClaimsJws(token) .getBody(); System.out.println(claims); }登录完成后生成令牌定义jwt令牌生成工具类登录完成后调用工具类生成jwt令牌并返回package com.itwyz.demo2.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 final String SECRET_KEY aXR3eXo; // 过期时间12小时 private static final long EXPIRATION 12 * 60 * 60 * 1000; /** * 生成 JWT 令牌 * * param claims 自定义数据 * return 返回生成的令牌字符串 */ public static String generateToken(MapString, Object claims) { return Jwts.builder() .signWith(SignatureAlgorithm.HS256, SECRET_KEY) .addClaims(claims) .setExpiration(new Date(System.currentTimeMillis() EXPIRATION)) .compact(); } /** * 解析 JWT 令牌 * * param token 要解析的令牌字符串 * return 返回解析后的 Claims 数据 */ public static Claims parseToken(String token) { return Jwts.parser() .setSigningKey(SECRET_KEY) .parseClaimsJws(token) .getBody(); } }Slf4j RestController() RequestMapping() public class LoginController { Autowired private UserService userService; PostMapping(/login) public LoginInfo Login(RequestBody User user){ LoginInfo info userService.login(user); if(info!null){ log.info(登录成功{},info); //生成Jwt令牌 MapString,Object claimsnew HashMap(); claims.put(id,info.getId()); claims.put(username,info.getUsername()); String jwt JwtUtils.generateToken(claims); return new LoginInfo(info.getId(),info.getUsername(), info.getPassword(), jwt); } return null; } }FilterFilter过滤器可以把对资源的请求拦截下来从而实现一些特殊的功能启动类上加ServeletComponentScanWebFilter(urlPatterns /*) Slf4j public class DemoFilter implements Filter { Override public void init(FilterConfig filterConfig) throws ServletException { log.info(过滤器初始化); } Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { log.info(过滤器开始执行); filterChain.doFilter(servletRequest,servletResponse); } Override public void destroy() { log.info(过滤器销毁); } }令牌校验package com.itwyz.demo2.filter; import com.itwyz.demo2.utils.JwtUtils; import jakarta.servlet.*; import jakarta.servlet.annotation.WebFilter; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import java.io.IOException; WebFilter(urlPatterns /*) Slf4j public class TokenFilter implements Filter { Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request (HttpServletRequest) servletRequest; HttpServletResponse response (HttpServletResponse) servletResponse; //1.获取到请求路径 String requestURI request.getRequestURI(); //2.判断是否是登录请求如果路径包含/login放行 if(requestURI.contains(/login)){ filterChain.doFilter(request,response); return; } //3.获取请求头中的token String token request.getHeader(token); //4.判读token是否为空如果为空返回错误信息 if(tokennull|| token.isEmpty()){ log.info(令牌为空,响应401); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); return; } //5.如果Token存在校验令牌如果校验失败返回错误信息 try { JwtUtils.parseToken(token); } catch (Exception e) { log.info(令牌校验不通过响应401); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); return; } //6.校验通过放行 log.info(令牌校验通过放行); filterChain.doFilter(request,response); } }放行后访问对应资源访问完成后还会回到Filter中并执行之后的操作一个web应用中可以配置多个过滤器这多个过滤器形成了一个过滤器链注解配置的Filter优先级是按照过滤器类名的自然排序Interceptorpackage com.itwyz.demo2.intercepter; import com.itwyz.demo2.utils.JwtUtils; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; Slf4j Component public class TokenIntercepter implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //3.获取请求头中的token String token request.getHeader(token); //4.判读token是否为空如果为空返回错误信息 if(tokennull || token.isEmpty()){ log.info(令牌为空,响应401); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); return false; } //5.如果Token存在校验令牌如果校验失败返回错误信息 try { JwtUtils.parseToken(token); } catch (Exception e) { log.info(令牌校验不通过响应401); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); return false; } //6.校验通过放行 log.info(令牌校验通过放行); return true; } }package com.itwyz.demo2.config; import com.itwyz.demo2.intercepter.TokenIntercepter; 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 { Autowired private TokenIntercepter tokenIntercepter; Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(tokenIntercepter) .addPathPatterns(/**) //拦截所有请求 .excludePathPatterns(/login); //不拦截登录请求 } }