2026.6.18笔记

1. 统一返回Result类优势

接口输出标准化,前端仅需一套通用解析逻辑;
静态工厂方法简化代码,不用每次new对象;
泛型兼容字符串、实体、集合等全部业务数据类型。

2. 全局异常处理器优势

消除项目中大量冗余try-catch代码,业务代码更纯粹;
异常统一拦截、统一返回格式,前后端协作更规范;
集中打印异常堆栈,便于线上/线下排查问题。

3. 企业拓展优化方向(后续可完善)

自定义业务异常类,区分参数错误、权限不足、数据不存在等不同code;
新增参数校验异常MethodArgumentNotValidException捕获;
引入日志框架(SLF4J)替换e.printStackTrace(),持久化异常日志;
封装分页专用返回对象,拓展Result分页字段。

4.JWT工具类 & 登录接口开发

核心解决痛点
实现用户无状态登录认证,登录成功下发Token,后续接口凭Token识别登录用户。

环境准备

pom.xml引入JJWT JWT加密依赖、jaxb兼容依赖,刷新Maven加载包;application.yml配置JWT加密密钥、Token过期时长(7天)。

封装JwtUtil工具类

放在util包,添加@Component交给Spring管理,通过@Value读取yml密钥配置,提供生成Token、解析Token、提取用户ID、校验Token有效性四个核心方法。

分层开发登录业务

DTO:UserLoginDTO接收前端账号密码入参;
Service层:UserService定义登录接口,UserServiceImpl通过MyBatis-Plus条件构造器查询数据库用户,账号密码匹配则生成JWT,不匹配返回空;
Controller层:UserController提供/user/loginPOST接口,接收登录参数,调用service生成Token,用Result封装返回。

Postman验证登录

POST请求携带JSON账号密码,登录成功返回携带Token的标准JSON,这串凭证是后续所有需要登录接口的通行凭证。

5.拦截器Token校验 + ThreadLocal存储登录用户

UserContext线程工具类

基于ThreadLocal实现线程隔离存储,存放当前登录用户ID,提供存、取、清除方法;请求结束自动清空,避免线程复用导致数据错乱。

JwtInterceptor登录拦截器

实现HandlerInterceptor,前置拦截所有请求:从请求头Authorization提取Bearer开头的Token,校验有效后解析用户ID存入UserContext;Token无效直接返回401未登录JSON,拦截接口访问。

MVC配置类注册拦截器

InterceptorConfig配置拦截规则:拦截全部接口,放行登录、注册无需鉴权的接口;配置完成后所有新闻发布/修改/删除接口都会强制校验登录状态。

6.新闻模块完整CRUD + 资源权限控制

入参DTO拆分

NewsAddDTO:发布新闻接收标题、内容;NewsUpdateDTO:修改新闻接收新标题、内容,按需传参,精简接口入参。

NewsController五层接口(RESTful规范)

POST /news/add:发布新闻,从UserContext获取登录用户ID绑定新闻发布人;
GET /news/page:分页查询全部新闻,无需登录,按发布时间倒序;
GET /news/{id}:新闻详情,自动累加浏览量,无需登录;
PUT /news/{id}:修改新闻,校验新闻发布人是否等于当前登录用户,非本人禁止修改;
DELETE /news/{id}:删除新闻,同修改权限校验,仅可操作自己发布内容。

Postman测试流程

调用/user/login登录复制Token;
访问新闻相关接口,在Authorization栏填入Bearer Token;
发送新增请求,数据库自动插入带用户ID的新闻数据;无Token/非本人操作会直接返回业务错误提示。

7.Vue前端 + SpringBoot后端联调实战

前端代码改造

request.js统一axios请求基地址改为后端 http://localhost:8080
封装登录请求方法login(),发送POST请求到后端登录接口;
页面Login.vue登录逻辑改造:接收后端标准Result返回,code=200则提取Token存入全局状态,跳转首页;登录失败展示后端返回的错误文案。

跨域问题踩坑与解决

前端运行在5173端口、后端8080端口,浏览器同源策略拦截请求,报错CORS跨域;临时解决方案:所有Controller类添加@CrossOrigin(origins = "http://localhost:5173")允许前端域名跨域访问,重启后端生效。

完整联调流程

启动SpringBoot后端项目;
前端项目执行npm run dev启动;
页面输入测试账号testuser、密码123456,点击登录;
登录成功自动跳转首页,浏览器控制台打印存储的Token,前端可正常调用新闻列表等公开接口。

1:创建通用返回类 Result

存放路径:com.weitoutiao.common.Result
泛型支持任意类型业务数据返回,内置静态方法快速构建成功/失败响应。

package com.weitoutiao.common;

import lombok.Data;

@Data
public class Result<T> {
    // 状态码
    private Integer code;
    // 提示信息
    private String message;
    // 业务数据
    private T data;

    // 私有构造,禁止外部new,统一使用静态方法创建对象
    private Result(Integer code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    // 成功:携带数据
    public static <T> Result<T> success(T data) {
        return new Result<>(200, "success", data);
    }

    // 成功:仅返回提示文案,无数据
    public static <T> Result<T> success(String message) {
        return new Result<>(200, message, null);
    }

    // 失败:统一服务异常,code固定500
    public static <T> Result<T> error(String message) {
        return new Result<>(500, message, null);
    }
}
#2:创建全局异常处理器 GlobalExceptionHandler
存放路径:com.weitoutiao.common.GlobalExceptionHandler
拦截所有Controller抛出的运行时异常,打印堆栈日志并封装成统一Result返回。
```java
package com.weitoutiao.common;

import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class GlobalExceptionHandler {

    // 捕获所有运行时异常
    @ExceptionHandler(RuntimeException.class)
    public Result<?> handleRuntimeException(RuntimeException e) {
        // 打印异常堆栈,方便后端定位bug
        e.printStackTrace();
        // 异常信息封装统一返回格式
        return Result.error(e.getMessage());
    }
}
#3:改造Controller,使用统一返回体
存放路径:com.weitoutiao.controller.HelloController
所有接口返回值统一改为Result<T>,调用Result.success()快速构建响应。
```java
package com.weitoutiao.controller;

import com.weitoutiao.common.Result;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @GetMapping("/hello")
    public Result<String> hello() {
        // 调用静态方法,统一封装返回
        return Result.success("微头条后端启动成功!");
    }
}
#4:项目完整目录结构
src/main/java/com/weitoutiao
├── common                // 通用工具类包
│   ├── GlobalExceptionHandler  // 全局异常处理器
│   └── Result                 // 统一返回封装类
├── config                // 配置类
├── controller            // 控制器
│   └── HelloController
├── entity                // 实体类
├── mapper                // Mybatis Mapper
├── service               // 业务层
└── WeiTouTiaoSpringBootApplication // 启动类
posted @ 2026-06-18 22:37  一口小鑫  阅读(6)  评论(0)    收藏  举报