1. 项目概述:SSM269家庭美食食谱网站系统
最近在开发一个基于SSM(Spring+SpringMVC+MyBatis)和Vue.js的家庭美食食谱网站系统,这个项目将传统Java后端框架与现代前端技术相结合,打造一个功能完善、用户体验良好的美食分享平台。作为一名全栈开发者,我在这个项目中负责从数据库设计到前端展示的完整实现,过程中积累了不少值得分享的经验。
这个系统主要面向家庭用户和美食爱好者,提供食谱发布、收藏、搜索和社交互动等功能。后端采用SSM框架搭建RESTful API,前端使用Vue.js构建响应式单页应用,数据库选用MySQL存储结构化数据。整个开发过程涉及前后端分离架构、跨域问题解决、性能优化等多个技术要点。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术选型与架构设计
2.1 后端技术栈:SSM框架详解
SSM框架组合是Java Web开发的经典选择,在本项目中我们使用的是:
- Spring 5.x:作为核心控制反转(IoC)容器,管理所有Bean的生命周期
- Spring MVC:处理HTTP请求和响应,实现RESTful接口
- MyBatis 3.x:持久层框架,与MySQL数据库交互
- Spring Boot 2.4:简化配置和部署(虽然不是传统SSM的一部分,但实际开发中我们加入了Spring Boot来提高效率)
提示:在实际开发中,我们使用了Spring Boot来简化SSM框架的配置,这大大减少了XML配置文件的编写量。
2.2 前端技术栈:Vue.js生态
前端部分我们选择了Vue.js作为核心框架,配合以下技术:
- Vue 2.x:主流稳定版本,提供响应式数据绑定和组件化开发
- Vue Router:实现前端路由和页面跳转
- Vuex:状态管理,共享用户登录状态等全局数据
- Element UI:提供美观的UI组件,加速开发
- Axios:处理HTTP请求,与后端API交互
2.3 数据库设计:MySQL优化实践
食谱网站的核心数据包括用户信息、食谱详情、食材分类等。我们设计了以下主要表结构:
sql复制CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(100) NOT NULL,
`avatar` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username_UNIQUE` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `recipe` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(100) NOT NULL,
`description` text,
`user_id` int(11) NOT NULL,
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `fk_recipe_user_idx` (`user_id`),
CONSTRAINT `fk_recipe_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
3. 核心功能实现
3.1 用户认证与授权
用户系统是网站的基础,我们实现了完整的注册、登录、权限控制流程:
- 密码加密存储:使用BCryptPasswordEncoder对密码进行加密
- JWT认证:采用JSON Web Token实现无状态认证
- 权限控制:基于Spring Security实现方法级别的权限控制
后端关键代码示例:
java复制@RestController
@RequestMapping("/api/auth")
public class AuthController {
@Autowired
private UserService userService;
@Autowired
private JwtTokenProvider jwtTokenProvider;
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody LoginRequest request) {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
request.getUsername(),
request.getPassword()
)
);
SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = jwtTokenProvider.generateToken(authentication);
return ResponseEntity.ok(new JwtAuthenticationResponse(jwt));
}
}
3.2 食谱管理功能
食谱是系统的核心内容,我们实现了:
- CRUD操作:创建、读取、更新、删除食谱
- 富文本编辑:集成Quill编辑器支持图文混排
- 分类标签:支持为食谱添加多个分类标签
- 搜索功能:基于Elasticsearch实现全文检索
前端Vue组件示例:
vue复制<template>
<div class="recipe-editor">
<el-form :model="recipeForm" label-width="80px">
<el-form-item label="食谱标题">
<el-input v-model="recipeForm.title"></el-input>
</el-form-item>
<el-form-item label="食谱描述">
<quill-editor v-model="recipeForm.content"></quill-editor>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm">保存</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
data() {
return {
recipeForm: {
title: '',
content: ''
}
}
},
methods: {
async submitForm() {
try {
await this.$axios.post('/api/recipes', this.recipeForm)
this.$message.success('食谱保存成功')
this.$router.push('/recipes')
} catch (error) {
this.$message.error('保存失败: ' + error.message)
}
}
}
}
</script>
4. 项目部署与优化
4.1 前后端分离部署
我们采用了典型的前后端分离部署方案:
- 后端部署:使用Spring Boot内嵌Tomcat,打包成JAR文件直接运行
- 前端部署:使用Nginx作为静态资源服务器
- 跨域解决:配置Nginx反向代理,避免浏览器跨域问题
Nginx配置示例:
nginx复制server {
listen 80;
server_name food.example.com;
location / {
root /var/www/food-frontend/dist;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
4.2 性能优化实践
在开发过程中,我们实施了多项性能优化措施:
-
数据库优化:
- 为常用查询字段添加索引
- 使用连接池(HikariCP)管理数据库连接
- 对大文本字段进行垂直分表
-
前端优化:
- 使用Vue的异步组件实现路由懒加载
- 对静态资源进行Gzip压缩
- 实现图片懒加载,减少初始请求量
-
缓存策略:
- 使用Redis缓存热门食谱数据
- 实现HTTP缓存头,利用浏览器缓存
5. 开发中的挑战与解决方案
5.1 文件上传与存储
食谱系统需要处理大量图片上传,我们实现了:
- 前端上传组件:基于Element UI的Upload组件进行二次开发
- 后端处理:使用Spring的MultipartFile接收文件
- 存储方案:本地存储与阿里云OSS双备份
关键代码片段:
java复制@PostMapping("/upload")
public ResponseEntity<String> uploadImage(@RequestParam("file") MultipartFile file) {
if (file.isEmpty()) {
return ResponseEntity.badRequest().body("请选择文件");
}
try {
String fileName = UUID.randomUUID() + getFileExtension(file.getOriginalFilename());
Path path = Paths.get(uploadDir, fileName);
Files.copy(file.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING);
// 同时上传到OSS
ossClient.putObject(bucketName, fileName, file.getInputStream());
return ResponseEntity.ok("/uploads/" + fileName);
} catch (IOException e) {
return ResponseEntity.status(500).body("上传失败");
}
}
5.2 前后端数据交互规范
为确保前后端协作顺畅,我们制定了严格的接口规范:
-
统一响应格式:
json复制{ "code": 200, "message": "success", "data": {...} } -
错误处理:
- 400 Bad Request:客户端请求错误
- 401 Unauthorized:未授权
- 403 Forbidden:无权限
- 500 Internal Server Error:服务器内部错误
-
API文档:使用Swagger UI自动生成接口文档
5.3 移动端适配
虽然主要面向桌面用户,我们也考虑了移动端体验:
- 响应式布局:使用Flex和Grid布局实现自适应
- 触摸优化:增大点击区域,优化手势操作
- 性能调优:针对移动网络优化资源加载策略
6. 项目扩展与未来规划
目前系统已经实现了基本功能,但还有不少可以扩展的方向:
-
社交功能增强:
- 用户关注系统
- 食谱评论和点赞
- 私信功能
-
智能推荐:
- 基于用户行为的个性化推荐
- 季节性食谱推荐
- 食材替代建议
-
移动应用:
- 开发React Native或Flutter版本
- 增加拍照识别食材功能
在实际开发过程中,我深刻体会到前后端分离架构的优势,特别是在团队协作和独立部署方面。同时,选择成熟稳定的技术栈(SSM+Vue)大大降低了开发风险,丰富的社区资源也帮助我们快速解决了遇到的问题。
