Java Web 开发详细流程
🧭 一、项目立项与需求分析阶段(0%)
1.1 商业需求确认
- 与产品经理沟通核心业务目标
- 目标:构建一个图书管理系统
- 用户:图书管理员、普通用户
- 功能:登录、查看、增删改图书、权限控制、分页、搜索
1.2 输出文档
- PRD(产品需求文档)
- ER图(数据建模)
- UML 用例图
- 接口草图(API Mock 文档)
- 项目甘特图 / 工作排期(Jira/TAPD)
🧱 二、系统设计与环境准备阶段(10%)
2.1 技术栈选择(通用、可复用)
层级 | 技术选型 |
---|---|
前端模板引擎 | Thymeleaf、Bootstrap |
控制层 | Spring Boot Web MVC |
服务层 | Spring @Service + AOP |
DAO 层 | Spring Data JPA + Hibernate |
数据库 | MySQL(可选 PostgreSQL) |
安全模块 | Spring Security + Session/Cookie |
配置管理 | application.yml + profiles |
单元测试 | JUnit5 + Mockito |
集成测试 | MockMvc + TestContainers |
2.2 开发工具准备
工具类型 | 建议 |
---|---|
IDE | IntelliJ IDEA Ultimate |
构建工具 | Maven |
版本控制 | Git + GitHub/GitLab |
数据库 | MySQL 8 + Navicat |
开发数据库 | dev_bookdb |
浏览器插件 | Postman / REST Client |
日志工具 | Logback + JSON Format |
2.3 项目初始化(Spring Boot)
使用 Spring Initializr 初始化:
- Group:
com.example
- Artifact:
bookmanager
- Packaging:Jar
- Java:17
- Dependencies:
- Spring Web
- Spring Data JPA
- Thymeleaf
- MySQL Driver
- Spring Boot DevTools
- Lombok(可选)
📐 三、数据库设计与模型映射(20%)
3.1 数据库设计
用 Navicat 或 dbdiagram.io 画出 ER 图:
- 用户表(users)
- 图书表(books)
- 管理员角色表(roles)
sql复制编辑CREATE TABLE users (id BIGINT PRIMARY KEY AUTO_INCREMENT,username VARCHAR(50) NOT NULL UNIQUE,password VARCHAR(100),role ENUM('USER', 'ADMIN')
);CREATE TABLE books (id BIGINT PRIMARY KEY AUTO_INCREMENT,title VARCHAR(100),author VARCHAR(100),price DOUBLE
);
3.2 实体类映射
使用 JPA 实体类标注:
java复制编辑@Entity
public class Book {@Id @GeneratedValueprivate Long id;private String title;private String author;private Double price;
}
⚙️ 四、项目分层架构设计(30%)
4.1 分层思想(经典 4 层架构)
javascript复制编辑Controller(Web控制层) ← 接收请求、返回视图或 JSON
↓
Service(业务逻辑层) ← 处理事务逻辑
↓
Repository(数据访问层) ← 连接数据库
↓
Entity(数据模型层) ← POJO、映射表
4.2 包结构设计
bash复制编辑com.example.bookmanager
├── controller # 控制器
├── service # 业务逻辑
├── repository # 数据库访问
├── entity # 数据模型
├── config # 配置类
├── security # 登录权限
└── BookManagerApplication.java
🛠️ 五、模块开发详细步骤(40%~70%)
5.1 编写实体类 Book
、User
配合数据库映射使用 @Entity
、@Column
、@Id
注解
5.2 编写 Repository 接口
java复制编辑public interface BookRepository extends JpaRepository<Book, Long> {List<Book> findByTitleContaining(String keyword);
}
5.3 编写业务 Service 层
java复制编辑@Service
public class BookService {@Autowiredprivate BookRepository repo;public List<Book> listAll() {return repo.findAll();}public void save(Book book) {repo.save(book);}
}
5.4 编写控制器 Controller 层
java复制编辑@Controller
public class BookController {@Autowiredprivate BookService service;@GetMapping("/")public String viewHomePage(Model model) {model.addAttribute("listBooks", service.listAll());return "index";}@PostMapping("/save")public String saveBook(@ModelAttribute("book") Book book) {service.save(book);return "redirect:/";}
}
5.5 页面开发(Thymeleaf 模板)
在 resources/templates/
下:
- index.html:主页
- new_book.html:添加页面
- edit_book.html:编辑页面
🔐 六、登录权限管理模块(80%)
6.1 集成 Spring Security
xml复制编辑<!-- pom.xml -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>
6.2 配置用户名密码
yaml复制编辑spring:security:user:name: adminpassword: admin123
或自定义认证逻辑 + 数据库存储用户密码 + BCrypt 加密。
🔍 七、测试、异常处理、优化阶段(90%)
7.1 单元测试
java复制编辑@SpringBootTest
class BookServiceTest {@Autowired BookService service;@Testvoid testListAll() {List<Book> books = service.listAll();assertFalse(books.isEmpty());}
}
7.2 异常处理(全局异常)
java复制编辑@ControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)public String handleException(Exception e, Model model) {model.addAttribute("error", e.getMessage());return "error";}
}
📦 八、构建、部署、上线(100%)
8.1 项目打包
bash复制编辑
mvn clean package
生成 bookmanager-0.0.1-SNAPSHOT.jar
8.2 运行方式
bash复制编辑
java -jar target/bookmanager-0.0.1-SNAPSHOT.jar
8.3 Docker 化部署
dockerfile复制编辑FROM openjdk:17
ADD target/bookmanager.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
bash复制编辑docker build -t bookmanager .
docker run -p 8080:8080 bookmanager
8.4 发布流程(传统方式)
- 上传 Jar 到服务器
- 使用 systemd 管理后台进程
- nginx 做反向代理,绑定域名
📊 九、整体项目节奏与时间分布(实际开发)
阶段 | 时间占比 | 说明 |
---|---|---|
需求分析与设计 | 10% | 通常 1~2 天 |
环境准备与初始化 | 5% | 项目生成 + 配置 + DB连接 |
模块开发 | 40% | 重点开发,持续集成 |
页面开发 + 安全 | 15% | UI 渲染、登录校验 |
测试与优化 | 20% | 单元、接口、异常、性能 |
构建 + 部署上线 | 10% | Docker 或 Jar 发布 |
🧩 十、高级功能
🔍 1. 搜索与分页功能(Spring Data JPA + Thymeleaf)
✅ 功能目标:
- 支持用户按关键字搜索图书
- 每页显示固定数量(如 10 条)
📦 依赖:
Spring Boot 已内置分页支持,无需额外依赖
🧠 Service 层实现:
java复制编辑public Page<Book> listAll(int pageNum, String keyword) {Pageable pageable = PageRequest.of(pageNum - 1, 10); // 第0页起if (keyword != null && !keyword.isEmpty()) {return repo.findByTitleContaining(keyword, pageable);}return repo.findAll(pageable);
}
📚 Repository 接口:
java复制编辑
Page<Book> findByTitleContaining(String keyword, Pageable pageable);
🌐 Controller 控制器:
java复制编辑@GetMapping("/")
public String viewHomePage(@RequestParam(defaultValue = "1") int page,@RequestParam(required = false) String keyword,Model model) {Page<Book> bookPage = service.listAll(page, keyword);model.addAttribute("bookPage", bookPage);model.addAttribute("currentPage", page);model.addAttribute("keyword", keyword);return "index";
}
🖼️ 页面模板 index.html(简化):
html复制编辑<form method="get" action="/"><input type="text" name="keyword" placeholder="搜索书名" value="${keyword}"><button type="submit">搜索</button>
</form><div th:each="book : ${bookPage.content}"><p th:text="${book.title}"></p>
</div><div><span th:text="'第 ' + ${currentPage} + ' 页'"></span><a th:href="@{'/?page=' + (${currentPage} - 1) + '&keyword=' + ${keyword}}">上一页</a><a th:href="@{'/?page=' + (${currentPage} + 1) + '&keyword=' + ${keyword}}">下一页</a>
</div>
🧵 2. 文件上传(Multipart + 本地存储)
✅ 功能目标:
- 图书添加时上传封面图
📦 Maven 依赖(已内置)
Spring Boot 自动启用 Multipart
🧠 配置文件:
yaml复制编辑spring:servlet:multipart:enabled: truemax-file-size: 2MBmax-request-size: 5MBupload:dir: uploads/
📂 Controller 示例:
java复制编辑@PostMapping("/upload")
public String uploadFile(@RequestParam("file") MultipartFile file) throws IOException {String uploadDir = "uploads/";String filename = UUID.randomUUID() + "_" + file.getOriginalFilename();Path path = Paths.get(uploadDir + filename);Files.createDirectories(path.getParent());Files.write(path, file.getBytes());return "redirect:/?uploadSuccess=true";
}
📋 HTML 上传表单:
html复制编辑<form method="post" action="/upload" enctype="multipart/form-data"><input type="file" name="file" /><button type="submit">上传</button>
</form>
🛡️ 3. JWT 用户认证(前后端分离准备)
✅ 功能目标:
- 用户登录后返回 JWT
- 前端携带 token 访问接口
📦 添加依赖:
xml复制编辑<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.11.5</version>
</dependency>
🧠 JWT 工具类:
java复制编辑public class JwtUtil {private static final String SECRET_KEY = "secret123";public static String generateToken(String username) {return Jwts.builder().setSubject(username).setIssuedAt(new Date()).setExpiration(new Date(System.currentTimeMillis() + 86400000)) // 1天.signWith(SignatureAlgorithm.HS512, SECRET_KEY).compact();}public static String extractUsername(String token) {return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().getSubject();}
}
🚪 登录接口返回 JWT:
java复制编辑@RestController
public class AuthController {@PostMapping("/api/login")public ResponseEntity<?> login(@RequestBody LoginRequest login) {if (login.getUsername().equals("admin") && login.getPassword().equals("1234")) {String token = JwtUtil.generateToken(login.getUsername());return ResponseEntity.ok(Map.of("token", token));}return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid credentials");}
}
🔐 使用 JWT 做权限过滤器:
自定义 OncePerRequestFilter
解码并设置 SecurityContextHolder
,可在需要认证的接口中通过 @AuthenticationPrincipal
拿用户。
🚦 4. 接口限流(Rate Limiting)
✅ 功能目标:
- 每 IP 每分钟最多请求 N 次(比如 20 次)
📦 方法一:使用 Bucket4j(令牌桶)
xml复制编辑<dependency><groupId>com.github.vladimir-bukhtoyarov</groupId><artifactId>bucket4j-core</artifactId><version>8.4.0</version>
</dependency>
💡 拦截器实现(伪代码):
java复制编辑@Component
public class RateLimitInterceptor extends HandlerInterceptorAdapter {private final Map<String, Bucket> ipBucketMap = new ConcurrentHashMap<>();private Bucket resolveBucket(String ip) {return ipBucketMap.computeIfAbsent(ip, key ->Bucket4j.builder().addLimit(Bandwidth.classic(20, Refill.greedy(20, Duration.ofMinutes(1)))).build());}@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {String ip = request.getRemoteAddr();Bucket bucket = resolveBucket(ip);if (bucket.tryConsume(1)) {return true;}response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());response.getWriter().write("Rate limit exceeded");return false;}
}
然后注册到 WebMvcConfigurer 的 addInterceptors()
。
🏁 整体功能架构整合图
plaintext复制编辑[Spring Boot + Spring Security + JPA]↓ ↓ ↓JWT认证 分页搜索 文件上传↓ ↓ ↓REST风格接口 HTML页面 本地磁盘↓接口限流(Bucket4j)
✅ 总结:完整流程图(开发视角)
plaintext复制编辑[需求 → 技术选型 → 架构 → 实体建模 → DB设计]↓[项目初始化 → 多层结构 → Controller/Service/Repo]↓[页面开发 + Thymeleaf + Bootstrap]↓[登录权限 + 测试 + 异常处理]↓[Maven打包 + Docker部署 + 上线发布]