文章目录
- 一、综合性练习
-
- [1.1 加法计算器](#1.1 加法计算器)
-
- [1.1.1 需求与准备](#1.1.1 需求与准备)
- [1.1.2 前后端交互接口约定](#1.1.2 前后端交互接口约定)
- [1.1.3 代码实现](#1.1.3 代码实现)
- [1.1.4 运行测试](#1.1.4 运行测试)
- [1.2 用户登录](#1.2 用户登录)
-
- [1.2.1 需求与准备](#1.2.1 需求与准备)
- [1.2.2 前后端交互接口约定](#1.2.2 前后端交互接口约定)
- [1.2.3 代码实现](#1.2.3 代码实现)
- [1.2.4 运行测试](#1.2.4 运行测试)
- [1.3 留言板](#1.3 留言板)
-
- [1.3.1 需求与准备](#1.3.1 需求与准备)
- [1.3.2 工具与依赖](#1.3.2 工具与依赖)
- [1.3.3 前后端交互接口约定](#1.3.3 前后端交互接口约定)
- [1.3.4 代码实现](#1.3.4 代码实现)
- [1.3.5 运行测试](#1.3.5 运行测试)
- [1.4 图书管理系统(基础版)](#1.4 图书管理系统(基础版))
-
- [1.4.1 需求与准备](#1.4.1 需求与准备)
- [1.4.2 前后端交互接口约定](#1.4.2 前后端交互接口约定)
- [1.4.3 代码实现](#1.4.3 代码实现)
- [1.4.4 运行测试](#1.4.4 运行测试)
- 二、应用分层
-
- [2.1 应用分层介绍](#2.1 应用分层介绍)
-
- [2.1.1 核心概念](#2.1.1 核心概念)
- [2.1.2 分层的必要性](#2.1.2 分层的必要性)
- [2.1.3 MVC与三层架构的关系](#2.1.3 MVC与三层架构的关系)
- [2.2 代码重构实践](#2.2 代码重构实践)
-
- [2.2.1 项目结构调整](#2.2.1 项目结构调整)
- [2.2.2 各层代码实现](#2.2.2 各层代码实现)
- [2.2.3 分层架构的优势](#2.2.3 分层架构的优势)
- 三、企业规范
-
- [3.1 命名规范](#3.1 命名规范)
-
- [3.1.1 类名规范](#3.1.1 类名规范)
- [3.1.2 方法名、参数名、变量名规范](#3.1.2 方法名、参数名、变量名规范)
- [3.1.3 包名规范](#3.1.3 包名规范)
- [3.1.4 其他命名风格参考](#3.1.4 其他命名风格参考)
- [3.2 编码规范](#3.2 编码规范)
-
- [3.2.1 注解使用规范](#3.2.1 注解使用规范)
- [3.2.2 代码格式规范](#3.2.2 代码格式规范)
- [3.2.3 依赖与工具规范](#3.2.3 依赖与工具规范)
- 四、总结
一、综合性练习
通过实际案例可深化对Spring MVC核心能力的理解,以下结合加法计算器、用户登录、留言板及图书管理系统四个案例,完整覆盖前后端交互流程、接口设计与数据处理逻辑。
1.1 加法计算器
1.1.1 需求与准备
需求为接收用户输入的两个整数,后端计算结果后返回给前端展示。准备工作需创建Spring Boot项目并引入Spring Web依赖,将前端页面calc.html放置在resources/static目录下,项目结构如下:
java
com.example.demo
DemoApplication
resources
static
calc.html
templates
application.properties
1.1.2 前后端交互接口约定
接口设计需明确请求路径、方式、参数与响应格式,具体如下:
| 接口要素 | 详情 |
|---|---|
| 请求路径 | /calc/sum |
| 请求方式 | GET/POST |
| 接口描述 | 计算两个整数相加 |
| 请求参数 | num1(Integer,必传,参与计算的第一个数)、num2(Integer,必传,参与计算的第二个数) |
| 响应数据 | Content-Type为text/html,响应内容为HTML格式的计算结果(如"计算机计算结果: 8") |
| 示例请求参数 | num1=5&num2=3 |
1.1.3 代码实现
- 后端代码 :创建
CalcController类,通过@RestController标识为控制器并返回数据,@RequestMapping映射请求路径,直接接收参数并计算返回结果:
java
@RestController
@RequestMapping("/calc")
public class CalcController {
@RequestMapping("/sum")
public String sum(Integer num1, Integer num2) {
Integer sum = num1 + num2;
return "<h1>计算机计算结果: " + sum + "</h1>";
}
}
- 前端代码:通过form表单指定请求路径与方式,提供输入框与提交按钮:
html
<form action="calc/sum" method="post">
<h1>计算器</h1>
数字1:<input name="num1" type="text"><br>
数字2:<input name="num2" type="text"><br>
<input type="submit" value=" 点击相加">
</form>
1.1.4 运行测试
启动项目后,访问http://127.0.0.1:8080/calc.html,输入两个整数(如5和16),点击"点击相加"按钮,页面会跳转至/calc/sum并显示计算结果(如"计算机计算结果: 21")。
1.2 用户登录
1.2.1 需求与准备
需求为用户输入账号密码后,后端校验正确性:校验失败则前端弹窗提示,校验成功则跳转至首页并显示当前登录用户,且后续访问首页仍能保留登录状态。准备工作需将login.html(登录页)、index.html(首页)放置在resources/static目录下。
1.2.2 前后端交互接口约定
需设计两个核心接口:登录校验接口与登录用户查询接口:
- 登录校验接口
| 接口要素 | 详情 |
|----------------|----------------------------------------------------------------------|
| 请求路径 |/user/login|
| 请求方式 | POST |
| 接口描述 | 校验账号密码是否正确 |
| 请求参数 |userName(String,必传,校验的账号)、password(String,必传,校验的密码) |
| 响应数据 | Content-Type为text/html,响应内容为true(账号密码验证成功)或false(账号密码验证失败) | - 查询登录用户接口
| 接口要素 | 详情 |
|----------------|----------------------------------------------------------------------|
| 请求路径 |/user/getLoginUser|
| 请求方式 | GET |
| 接口描述 | 查询当前登录的用户 |
| 请求参数 | 无 |
| 响应数据 | Content-Type为text/html,响应内容为当前登录用户名(未登录则返回空) |
1.2.3 代码实现
- 后端代码 :创建
LoginController类,使用HttpSession存储登录用户信息,StringUtils.hasLength()判断参数是否为空,固定账号密码(zhangsan/123456)进行校验:
java
import jakarta.servlet.http.HttpSession;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user")
public class LoginController {
@RequestMapping("/login")
public boolean login(String userName, String password, HttpSession session) {
// 账号或密码为空时返回false
if (!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)) {
return false;
}
// 校验账号密码,正确则存储用户信息到Session
if ("zhangsan".equals(userName) && "123456".equals(password)) {
session.setAttribute("userName", userName);
return true;
}
return false;
}
@RequestMapping("/getLoginUser")
public String getLoginUser(HttpSession session) {
// 从Session中获取登录用户信息
String userName = (String) session.getAttribute("userName");
return StringUtils.hasLength(userName) ? userName : "";
}
}
- 前端代码 :登录页通过Ajax发送请求校验账号密码,成功则跳转首页;首页通过Ajax获取登录用户信息并展示:
- 登录页(
login.html):
- 登录页(
html
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script>
function login() {
$.ajax({
type: "post",
url: "/user/login",
data: {
"userName": $("#userName").val(),
"password": $("#password").val()
},
success: function (result) {
if (result) {
location.href = "/index.html"; // 登录成功跳转首页
} else {
alert("账号或密码有误."); // 登录失败弹窗提示
}
}
});
}
</script>
- 首页(
index.html):
html
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script>
$.ajax({
type: "get",
url: "/user/getLoginUser",
success: function (result) {
$("#loginUser").text(result); // 展示当前登录用户
}
});
</script>
1.2.4 运行测试
启动项目后,访问http://127.0.0.1:8080/login.html,输入正确账号密码(zhangsan/123456),登录成功后跳转至首页,首页显示"登录人:zhangsan";多次刷新首页仍能保留登录状态,重启服务器后登录状态丢失(因Session默认存储在内存)。
1.3 留言板
1.3.1 需求与准备
需求为用户输入留言人(谁)、接收人(对谁)、留言内容(说什么),提交后后端存储留言;页面加载时从后端获取所有历史留言并展示。准备工作需引入Lombok依赖简化实体类代码,将messagewall.html(留言板页面)放置在resources/static目录下。
1.3.2 工具与依赖
- Lombok介绍 :Lombok是Java工具库,通过注解自动生成
getter/setter、toString等方法,减少冗余代码。需在pom.xml引入依赖:
xml
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
- 核心注解 :
@Data注解可自动生成getter、setter、toString、equals、hashCode及无参构造方法,等价于@Getter + @Setter + @ToString + @EqualsAndHashCode + @NoArgsConstructor。
1.3.3 前后端交互接口约定
需设计两个接口:获取全部留言接口与发表新留言接口:
- 获取全部留言接口
| 接口要素 | 详情 |
|----------------|----------------------------------------------------------------------|
| 请求路径 |/message/getList|
| 请求方式 | GET |
| 接口描述 | 获取所有留言信息 |
| 响应数据 | JSON格式的留言列表,每条留言包含from(留言人)、to(接收人)、message(留言内容) | - 发表新留言接口
| 接口要素 | 详情 |
|----------------|----------------------------------------------------------------------|
| 请求路径 |/message/publish|
| 请求方式 | POST |
| 接口描述 | 提交新留言 |
| 请求参数 |from(String,必传,留言人)、to(String,必传,接收人)、message(String,必传,留言内容) |
| 响应数据 | JSON格式,ok: 1表示发表成功 |
1.3.4 代码实现
- 模型层 :创建
MessageInfo实体类,使用@Data注解简化代码:
java
import lombok.Data;
@Data
public class MessageInfo {
private String from;
private String to;
private String message;
}
- 后端代码 :创建
MessageController类,使用List<MessageInfo>存储留言(内存存储,重启服务器后数据丢失),提供接口处理留言获取与发表:
java
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
@RequestMapping("/message")
@RestController
public class MessageController {
// 存储留言信息(内存存储)
private List<MessageInfo> messageInfos = new ArrayList<>();
@RequestMapping("/getList")
public List<MessageInfo> getList() {
return messageInfos; // 返回所有留言
}
@RequestMapping("/publish")
public boolean publish(MessageInfo messageInfo) {
// 校验参数非空,非空则添加留言并返回true
if (StringUtils.hasLength(messageInfo.getFrom())
&& StringUtils.hasLength(messageInfo.getTo())
&& StringUtils.hasLength(messageInfo.getMessage())) {
messageInfos.add(messageInfo);
return true;
}
return false; // 参数为空则返回false
}
}
- 前端代码 :页面加载时调用
load()方法获取历史留言,点击提交按钮时调用submit()方法发表新留言并刷新页面:
html
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script>
// 页面加载时获取留言
load();
function load() {
$.ajax({
type: "get",
url: "/message/getList",
success: function (result) {
for (var message of result) {
var divE = "<div>" + message.from + "对" + message.to + "说:" + message.message + "</div>";
$(".container").append(divE); // 展示留言
}
}
});
}
// 提交留言
function submit() {
var from = $('#from').val();
var to = $('#to').val();
var say = $('#say').val();
if (from == '' || to == '' || say == '') {
return; // 参数为空不提交
}
$.ajax({
type: "post",
url: "/message/publish",
data: {
from: from,
to: to,
message: say
},
success: function (result) {
if (result) {
// 发表成功,添加新留言到页面并清空输入框
var divE = "<div>" + from + "对" + to + "说:" + say + "</div>";
$(".container").append(divE);
$('#from').val("");
$('#to').val("");
$('#say').val("");
} else {
alert("发表留言失败!");
}
}
});
}
</script>
1.3.5 运行测试
访问http://127.0.0.1:8080/messagewall.html,输入留言信息(如"黑猫""白猫""喵"),点击提交后,页面下方会实时显示新留言;关闭页面后重新打开,历史留言仍能正常加载(数据存储在服务器内存中)。
1.4 图书管理系统(基础版)
1.4.1 需求与准备
需求为实现用户登录与图书列表展示功能:用户输入账号密码登录,登录成功后跳转至图书列表页,页面展示图书ID、书名、作者、数量、定价等信息,支持后续扩展添加、修改、删除图书功能。准备工作需创建新项目并引入Spring Web、Lombok依赖,将login.html(登录页)、book_list.html(图书列表页)放置在resources/static目录下。
1.4.2 前后端交互接口约定
核心接口包括登录校验接口与图书列表获取接口:
- 登录校验接口
| 接口要素 | 详情 |
|----------------|----------------------------------------------------------------------|
| 请求路径 |/user/login|
| 请求方式 | POST |
| 请求参数 |name(String,必传,用户名)、password(String,必传,密码) |
| 响应数据 |true(登录成功)、false(登录失败) | - 图书列表获取接口
| 接口要素 | 详情 |
|----------------|----------------------------------------------------------------------|
| 请求路径 |/book/getList|
| 请求方式 | POST |
| 请求参数 | 无 |
| 响应数据 | JSON格式的图书列表,每条图书包含id(图书ID)、bookName(书名)、author(作者)、count(数量)、price(定价)、publish(出版社)、status(状态)、statusCN(状态中文含义) |
1.4.3 代码实现
- 模型层 :创建
BookInfo实体类,使用@Data注解简化代码:
java
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
public class BookInfo {
private Integer id; // 图书ID
private String bookName; // 书名
private String author; // 作者
private Integer count; // 数量
private BigDecimal price; // 定价
private String publish; // 出版社
private Integer status; // 状态(0-无效,1-可借阅,2-不可借阅)
private String statusCN; // 状态中文含义
private Date createTime; // 创建时间
private Date updateTime; // 更新时间
}
- 后端代码 :
- 登录控制器(
UserController):校验账号密码(固定为admin/admin),登录成功则存储用户名到Session:
- 登录控制器(
java
import jakarta.servlet.http.HttpSession;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user")
public class UserController {
@RequestMapping("/login")
public boolean login(String name, String password, HttpSession session) {
if (!StringUtils.hasLength(name) || !StringUtils.hasLength(password)) {
return false;
}
if ("admin".equals(name) && "admin".equals(password)) {
session.setAttribute("userName", name);
return true;
}
return false;
}
}
- 图书控制器(
BookController):通过mockData()方法模拟图书数据,处理图书状态中文转换并返回列表:
java
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
@RequestMapping("/book")
@RestController
public class BookController {
@RequestMapping("/getList")
public List<BookInfo> getList() {
List<BookInfo> books = mockData(); // 获取模拟图书数据
// 处理图书状态中文含义
for (BookInfo book : books) {
book.setStatusCN(book.getStatus() == 1 ? "可借阅" : "不可借阅");
}
return books;
}
// 模拟获取图书数据
private List<BookInfo> mockData() {
List<BookInfo> books = new ArrayList<>();
for (int i = 0; i < 5; i++) {
BookInfo book = new BookInfo();
book.setId(i);
book.setBookName("书籍" + i);
book.setAuthor("作者" + i);
book.setCount(i * 5 + 3);
book.setPrice(new BigDecimal(new Random().nextInt(100)));
book.setPublish("出版社" + i);
book.setStatus(1); // 默认设置为可借阅状态
books.add(book);
}
return books;
}
}
- 前端代码 :登录页通过Ajax校验账号密码并跳转,图书列表页通过Ajax获取数据并渲染表格:
- 登录页(
login.html):
- 登录页(
html
<script src="js/jquery.min.js"></script>
<script>
function login() {
$.ajax({
type: "post",
url: "/user/login",
data: {
"name": $("#userName").val(),
"password": $("#password").val()
},
success: function (result) {
if (result) {
location.href = "book_list.html"; // 登录成功跳转图书列表页
} else {
alert("账号或密码不正确!");
}
}
});
}
</script>
- 图书列表页(
book_list.html):
html
<script src="js/jquery.min.js"></script>
<script>
// 获取图书列表并渲染表格
function getBookList() {
$.ajax({
type: "get",
url: "/book/getList",
success: function (result) {
if (result != null) {
var finalHtml = "";
for (var book of result) {
finalHtml += '<tr>';
finalHtml += '<td><input type="checkbox" name="selectBook" value="' + book.id + '" class="book-select"></td>';
finalHtml += '<td>' + book.id + '</td>';
finalHtml += '<td>' + book.bookName + '</td>';
finalHtml += '<td>' + book.author + '</td>';
finalHtml += '<td>' + book.count + '</td>';
finalHtml += '<td>' + book.price + '</td>';
finalHtml += '<td>' + book.publish + '</td>';
finalHtml += '<td>' + book.statusCN + '</td>';
finalHtml += '<td><div class="op">';
finalHtml += '<a href="book_update.html?bookId=' + book.id + '">修改</a>';
finalHtml += '<a href="javascript:void(0)" onclick="deleteBook(' + book.id + ')">删除</a>';
finalHtml += '</div></td>';
finalHtml += "</tr>";
}
$("tbody").html(finalHtml); // 渲染表格数据
}
}
});
}
// 页面加载时调用获取图书列表方法
getBookList();
</script>
1.4.4 运行测试
启动项目后,访问http://127.0.0.1:8080/login.html,输入账号密码admin/admin,登录成功后跳转至图书列表页,页面会展示5条模拟图书数据,包含图书ID、书名、作者等信息,且状态列显示"可借阅"。
二、应用分层
随着项目功能复杂度提升,代码堆砌会导致维护困难,应用分层通过按职责划分模块,实现高内聚、低耦合,是企业级开发的核心设计思想。
2.1 应用分层介绍
2.1.1 核心概念
应用分层是将应用程序按职责划分为多个层次,各层次专注于自身功能,通过协同工作提供完整服务的设计思想。常见的分层方式为"三层架构",结合Spring MVC框架,后端分层可细分为:
- 表现层(Controller):接收前端请求,调用业务逻辑层处理,返回响应数据,是前后端交互的入口。
- 业务逻辑层(Service):处理核心业务逻辑,如数据校验、状态转换、业务规则判断等,协调数据访问层完成数据操作。
- 数据访问层(Dao):负责数据的增删改查操作,与数据库或其他数据源(如缓存、文件)交互,不包含业务逻辑。
- 模型层(Model):定义实体类,封装数据结构,对应数据库表或业务对象,是各层之间数据传递的载体。
2.1.2 分层的必要性
- 解耦需求:未分层时,代码中请求处理、业务逻辑、数据访问混合在一起,修改一处可能影响多处(如更换数据源需修改所有涉及数据操作的代码);分层后各层职责独立,降低层间依赖。
- 维护效率:开发人员可专注于某一层开发(如前端工程师负责表现层交互,后端工程师负责业务逻辑与数据访问),问题定位更精准(如数据错误只需排查数据访问层)。
- 扩展性:可轻松替换某一层的实现(如将Dao层的内存存储改为MySQL数据库,只需修改Dao层代码,Service与Controller层无需变动)。
2.1.3 MVC与三层架构的关系
MVC与三层架构均为软件工程中的架构模式,从不同角度实现解耦,二者并非替代关系,而是可共存互补:
- MVC:关注"数据展示与处理分离",将系统分为Model(模型,包含数据与业务逻辑)、View(视图,用户交互界面)、Controller(控制器,请求分发),适用于前后端未完全分离的场景。
- 三层架构:关注"数据处理维度的职责分离",将后端分为表现层(对应MVC的View+Controller)、业务逻辑层(对应MVC的Model核心业务逻辑)、数据访问层(对应MVC的Model数据操作),适用于前后端分离的后端开发。
- 核心目的:二者均以"高内聚、低耦合"为设计原则,MVC解决前端展示与后端处理的耦合,三层架构解决后端内部业务逻辑与数据访问的耦合。
2.2 代码重构实践
以图书管理系统的图书列表功能为例,基于分层思想对代码进行重构,明确各层职责与依赖关系。
2.2.1 项目结构调整
重构后的项目按分层划分包路径,结构如下:
java
com.example.demo
controller // 表现层(Controller)
BookController.java
UserController.java
service // 业务逻辑层(Service)
BookService.java
dao // 数据访问层(Dao)
BookDao.java
model // 模型层(Model)
BookInfo.java
DemoApplication.java // 项目启动类
resources
static // 静态资源(前端页面)
templates
application.properties
2.2.2 各层代码实现
- 模型层(Model) :
BookInfo类,封装图书数据,使用Lombok的@Data注解:
java
package com.example.demo.model;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
public class BookInfo {
private Integer id;
private String bookName;
private String author;
private Integer count;
private BigDecimal price;
private String publish;
private Integer status;
private String statusCN;
private Date createTime;
private Date updateTime;
}
- 数据访问层(Dao) :
BookDao类,负责模拟图书数据获取,仅包含数据操作,无业务逻辑:
java
package com.example.demo.dao;
import com.example.demo.model.BookInfo;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class BookDao {
// 模拟从数据源获取图书数据
public List<BookInfo> mockData() {
List<BookInfo> books = new ArrayList<>();
for (int i = 0; i < 5; i++) {
BookInfo book = new BookInfo();
book.setId(i);
book.setBookName("书籍" + i);
book.setAuthor("作者" + i);
book.setCount(i * 5 + 3);
book.setPrice(new BigDecimal(new Random().nextInt(100)));
book.setPublish("出版社" + i);
book.setStatus(1);
books.add(book);
}
return books;
}
}
- 业务逻辑层(Service) :
BookService类,调用Dao层获取数据,处理业务逻辑(图书状态中文转换):
java
package com.example.demo.service;
import com.example.demo.dao.BookDao;
import com.example.demo.model.BookInfo;
import java.util.List;
public class BookService {
// 调用Dao层获取数据并处理业务逻辑
public List<BookInfo> getBookList() {
BookDao bookDao = new BookDao();
List<BookInfo> books = bookDao.mockData();
// 业务逻辑:图书状态中文转换
for (BookInfo book : books) {
book.setStatusCN(book.getStatus() == 1 ? "可借阅" : "不可借阅");
}
return books;
}
}
- 表现层(Controller) :
BookController类,接收前端请求,调用Service层获取处理后的数据,返回响应:
java
package com.example.demo.controller;
import com.example.demo.model.BookInfo;
import com.example.demo.service.BookService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RequestMapping("/book")
@RestController
public class BookController {
@RequestMapping("/getList")
public List<BookInfo> getList() {
BookService bookService = new BookService();
return bookService.getBookList(); // 调用Service层获取数据并返回
}
}
2.2.3 分层架构的优势
- 职责清晰:各层仅关注自身职责,Controller不处理业务逻辑,Service不直接操作数据,Dao不包含业务规则,代码可读性提升。
- 降低耦合 :层间依赖通过接口或简单调用实现,如修改Dao层的数据源(从内存改为MySQL),只需修改
BookDao类,Service与Controller层无需改动。 - 复用性强:业务逻辑封装在Service层,可被多个Controller调用(如图书列表功能可被普通用户、管理员等不同角色的Controller复用)。
- 便于测试:可对各层单独测试,如通过Mock工具测试Service层业务逻辑,无需依赖真实数据源或前端请求。
三、企业规范
企业规范是保证团队协作效率、代码一致性的重要准则,以下为Spring MVC开发中常见的企业级命名与编码规范(具体以所在企业要求为准)。
3.1 命名规范
3.1.1 类名规范
- 使用大驼峰命名法 (所有单词首字母大写),如
UserController、BookService、BookInfo。 - 特殊例外:DO(数据对象)、BO(业务对象)、DTO(数据传输对象)、VO(视图对象)、AO(应用对象)等,类名可按业务场景简化,如
UserDO、BookDTO。
3.1.2 方法名、参数名、变量名规范
- 统一使用小驼峰命名法 (第一个单词首字母小写,后续单词首字母大写),如
getBookList()、userName、bookPrice。 - 方法名需体现业务含义,如获取图书列表用
getBookList(),而非method1();更新图书用updateBook(),而非modify()。
3.1.3 包名规范
- 统一使用小写字母 ,点分隔符之间为单个自然语义的英语单词,按分层或业务模块划分,如:
- 表现层:
com.example.demo.controller - 业务逻辑层:
com.example.demo.service - 数据访问层:
com.example.demo.dao - 模型层:
com.example.demo.model - 工具类:
com.example.demo.util
- 表现层:
3.1.4 其他命名风格参考
- 蛇形命名法 :用下划线(
_)分隔单词,多用于数据库表名、配置文件参数,如user_id、book_name。 - 脊柱命名法 :用短横线(
-)分隔单词,多用于URL路径、HTML标签属性,如/book-list、class="book-item"。
3.2 编码规范
3.2.1 注解使用规范
@RestController与@Controller区分:返回数据(如JSON、文本)用@RestController,返回静态页面用@Controller(需配合@ResponseBody返回数据)。@RequestMapping路径规范:URL路径最前面建议加/(如/book/getList),多层路径按业务模块划分(如/user/login、/book/update)。- 参数注解明确化:接收路径参数用
@PathVariable,接收JSON参数用@RequestBody,参数重命名用@RequestParam,避免参数绑定歧义。
3.2.2 代码格式规范
- 缩进:使用4个空格缩进,避免使用Tab键,保证不同编辑器下格式一致。
- 空行:方法之间、代码块之间保留空行,如Controller中不同接口方法之间空一行,提高可读性。
- 注释:核心业务逻辑、复杂算法需添加注释,注释内容简洁明了,说明"为什么做"而非"做了什么";类、方法可使用Javadoc注释,便于生成文档。
3.2.3 依赖与工具规范
- 依赖版本统一:项目中Spring Boot、Spring MVC、Lombok等依赖版本需统一,避免版本冲突,如Spring Boot版本统一为
3.2.0。 - 工具类使用:优先使用Spring提供的工具类(如
StringUtils),避免重复造轮子;自定义工具类需放在util包下,且方法设计为静态方法(如DateUtils.formatDate())。
四、总结
Spring MVC作为Java后端核心Web框架,其学习核心围绕"注解使用""前后端交互""分层设计"三大维度展开:
- 注解体系 :掌握
@RequestMapping(路由映射)、@RequestParam(参数重命名)、@RequestBody(接收JSON)、@PathVariable(路径参数)、@RestController(返回数据)等核心注解,是实现Spring MVC功能的基础。 - 交互流程 :请求处理需根据参数类型选择合适的接收方式(如单个参数直接接收、JSON参数用
@RequestBody),响应处理需区分返回数据与静态页面(@RestControllervs@Controller)。 - 分层设计:通过Controller(表现层)、Service(业务逻辑层)、Dao(数据访问层)的分层架构,实现代码解耦与复用,是企业级项目开发的标准模式。
- 工具与规范:Postman用于接口测试,Lombok简化实体类代码,企业规范保证团队协作效率,这些是提升开发效率的重要辅助。