前后端分离已成为企业级项目开发的标准架构。SpringBoot作为后端框架,配合Vue作为前端框架,是目前Java开发者最常用的技术栈之一。本文将从架构设计到具体实现,带你完成一个完整的前后端分离项目。

一、项目架构设计

技术选型

项目结构

项目根目录/ ├── backend/ # SpringBoot后端 │ ├── src/main/java/ │ │ ├── controller/ # 控制器层 │ │ ├── service/ # 业务逻辑层 │ │ ├── mapper/ # 数据访问层 │ │ ├── entity/ # 实体类 │ │ ├── config/ # 配置类 │ │ └── utils/ # 工具类 │ └── src/main/resources/ │ └── application.yml └── frontend/ # Vue前端 ├── src/ │ ├── views/ # 页面组件 │ ├── components/ # 公共组件 │ ├── api/ # 接口请求 │ ├── router/ # 路由配置 │ └── store/ # 状态管理

二、后端核心代码

统一响应结果封装

@Data @AllArgsConstructor @NoArgsConstructor public class Result<T> { private int code; private String message; private T data; public static <T> Result<T> success(T data) { return new Result<>(200, "操作成功", data); } public static <T> Result<T> error(String message) { return new Result<>(500, message, null); } }

用户控制器示例

@RestController @RequestMapping("/api/user") @CrossOrigin public class UserController { @Autowired private UserService userService; @GetMapping("/list") public Result<List<User>> getUserList( @RequestParam(defaultValue = "1") int page, @RequestParam(defaultValue = "10") int size) { Page<User> pageResult = userService.page( new Page<>(page, size)); return Result.success(pageResult.getRecords()); } @PostMapping("/add") public Result<User> addUser(@RequestBody User user) { userService.save(user); return Result.success(user); } @PutMapping("/update") public Result<Void> updateUser(@RequestBody User user) { userService.updateById(user); return Result.success(null); } @DeleteMapping("/{id}") public Result<Void> deleteUser(@PathVariable Long id) { userService.removeById(id); return Result.success(null); } }

三、前端请求封装

// api/request.js - Axios封装 import axios from 'axios' import { ElMessage } from 'element-plus' const request = axios.create({ baseURL: 'http://localhost:8080', timeout: 10000 }) // 请求拦截器:自动携带Token request.interceptors.request.use(config => { const token = localStorage.getItem('token') if (token) { config.headers.Authorization = `Bearer ${token}` } return config }) // 响应拦截器:统一错误处理 request.interceptors.response.use( response => response.data, error => { ElMessage.error(error.message || '请求失败') return Promise.reject(error) } ) export default request

四、跨域配置

@Configuration public class CorsConfig { @Bean public CorsFilter corsFilter() { CorsConfiguration config = new CorsConfiguration(); config.addAllowedOriginPattern("*"); config.setAllowCredentials(true); config.addAllowedMethod("*"); config.addAllowedHeader("*"); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); return new CorsFilter(source); } }
小贴士:开发阶段建议在 vite.config.js 中配置代理,避免跨域问题,生产环境再由Nginx统一处理。

五、部署配置

Nginx配置

server { listen 80; server_name your-domain.com; # 前端静态文件 location / { root /var/www/frontend/dist; index index.html; try_files $uri $uri/ /index.html; } # 后端API代理 location /api/ { proxy_pass http://localhost:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }

六、JWT登录认证实现

// 登录接口 @PostMapping("/login") public Result<String> login(@RequestBody LoginDTO dto) { User user = userService.findByUsername(dto.getUsername()); if (user == null || !passwordEncoder.matches( dto.getPassword(), user.getPassword())) { return Result.error("用户名或密码错误"); } // 生成JWT Token String token = jwtUtils.generateToken(user.getId()); return Result.success(token); } // 拦截器验证Token public class JwtInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String token = request.getHeader("Authorization"); if (token == null || !jwtUtils.validate(token)) { response.setStatus(401); return false; } return true; } }

七、常见实际案例与解决

❌ 跨域不生效

检查Nginx是否配置了OPTIONS请求转发,开发时建议用Vite代理

❌ 分页不生效

MyBatis-Plus分页需配置PaginationInterceptor,否则返回全部数据

❌ 热更新无效

IDEA需安装Lombok插件,并开启Settings > Compiler > 自动构建

❌ 打包后找不到静态资源

Vue构建后放到SpringBoot的resources/static目录,或用Nginx分离部署

总结:SpringBoot + Vue 是目前国内最流行的前后端分离方案。适合做后台管理系统、电商平台、企业官网等。建议先用脚手架搭建基础框架,再逐步添加业务功能。