Java MVC案例如何基础搭建:从零开始的Spring MVC项目实战指南
目录导读
- 什么是MVC模式?为何Java开发首选?
- 环境准备与项目初始化
- 核心配置:从web.xml到注解驱动
- 模型层(Model)实战:实体类与DAO层搭建
- 视图层(View)实现:JSP与模板引擎选择
- 控制器层(Controller)编写:请求映射与数据传递
- 完整案例:用户登录模块全流程演示
- 常见问题问答(FAQ)
什么是MVC模式?为何Java开发首选?
MVC(Model-View-Controller)是一种将应用程序的业务逻辑、数据和界面显示分离的架构模式,在Java生态中,Spring MVC是其最经典、最成熟的实现方案。

核心组件解析:
- Model(模型):负责数据封装和业务逻辑处理,通常包含实体类、DAO层、Service层。
- View(视图):负责界面展示,在Java中常用JSP、Thymeleaf或FreeMarker。
- Controller(控制器):接收用户请求,调用模型处理数据,返回视图响应。
为什么Java开发者必须掌握? 根据行业调研,超过76%的Java企业级项目采用Spring MVC架构,它能实现代码低耦合、提高可维护性,并且天然支持RESTful API开发。
问答环节:
问:MVC与三层架构是什么关系? 答:MVC是表现层模式,三层架构是系统级分层(表现层、业务层、数据层),两者互补:控制器属于表现层,模型包含业务层和数据层,视图是表现层的UI部分。
环境准备与项目初始化
前提工具列表:
- JDK 1.8+(推荐JDK 11或17)
- IDE:IntelliJ IDEA(社区版免费可用)或Eclipse
- Maven 3.6+(项目管理工具)
- Tomcat 9.0+(Servlet容器)
Maven项目快速搭建:
<!-- pom.xml核心依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.30</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
项目结构标准:
src/main/java
├── com.example.controller
├── com.example.model
├── com.example.dao
└── com.example.service
src/main/webapp
├── WEB-INF/web.xml
└── views/
核心配置:从web.xml到注解驱动
传统web.xml配置方式:
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-servlet.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
纯注解配置(推荐):
@Configuration
@EnableWebMvc
@ComponentScan("com.example.controller")
public class WebConfig implements WebMvcConfigurer {
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
}
注意:使用注解时需在web.xml中配置
ContextLoaderListener或使用AbstractAnnotationConfigDispatcherServletInitializer。
问答环节:
问:为什么我的Spring MVC项目启动404? 答:以下是三个常见原因:(1)未正确配置组件扫描包路径;(2)视图解析器前缀后缀配置错误;(3)控制器方法未添加
@ResponseBody或返回的视图名称不存在。
模型层(Model)实战:实体类与DAO层搭建
实体类示例:
public class User {
private int id;
private String username;
private String password;
// 标准getter/setter和构造方法省略
}
DAO层(模拟数据源):
@Repository
public class UserDao {
private static Map<Integer, User> users = new ConcurrentHashMap<>();
static {
users.put(1, new User(1, "admin", "123456"));
users.put(2, new User(2, "test", "password"));
}
public User findByUsername(String username) {
return users.values().stream()
.filter(u -> u.getUsername().equals(username))
.findFirst().orElse(null);
}
}
专业建议:实际开发中应使用MyBatis或JPA连接数据库,此处为演示仅用内存模拟。
视图层(View)实现:JSP与模板引擎选择
JSP视图示例(login.jsp):
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>用户登录</title></head>
<body>
<form action="${pageContext.request.contextPath}/user/login" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<input type="submit" value="登录">
</form>
<p style="color:red">${error}</p>
</body>
</html>
现代项目推荐: 如果是新项目,建议使用Thymeleaf代替JSP,Thymeleaf支持天然HTML5模板,更符合前后端分离趋势,且避免JSP编译产生的性能问题。
控制器层(Controller)编写:请求映射与数据传递
完整控制器代码:
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserDao userDao; // 实际应为UserService
@GetMapping("/login")
public String showLoginPage() {
return "login"; // 对应/WEB-INF/views/login.jsp
}
@PostMapping("/login")
public String handleLogin(@RequestParam String username,
@RequestParam String password,
Model model) {
User user = userDao.findByUsername(username);
if (user != null && user.getPassword().equals(password)) {
model.addAttribute("message", "登录成功!欢迎 " + username);
return "success";
} else {
model.addAttribute("error", "用户名或密码错误");
return "login";
}
}
}
关键注解说明:
@Controller:标记为控制器组件@RequestMapping:定义URL映射路径@RequestParam:绑定请求参数到方法参数Model:用于传递数据到视图
问答环节:
问:
@RestController与@Controller区别是什么? 答:@RestController=@Controller+@ResponseBody,用于RESTful API开发,返回JSON/XML数据而非视图页面,简单说:@Controller返回视图名,@RestController返回数据体。
完整案例:用户登录模块全流程演示
步骤流程演示:
- 启动Tomcat,访问
http://localhost:8080/项目名/user/login - 浏览器呈现登录表单(login.jsp)
- 输入用户名"admin"、密码"123456",点击登录
- Post请求到达
UserController.handleLogin()方法 - 模型层调用
UserDao.findByUsername()查询用户 - 密码验证成功,Model中添加"登录成功"消息
- 转发到success.jsp页面显示成功信息
核心代码运行逻辑图:
浏览器 → DispatcherServlet → HandlerMapping → Controller方法
↑ ↓
└── ViewResolver ←─ ModelAndView ←── Service
常见问题问答(FAQ)
Q1:Spring MVC项目运行时出现ClassNotFoundException如何处理?
A:检查Maven依赖是否完整下载,确认
spring-webmvc与Servlet-API版本兼容,建议使用Maven依赖树命令mvn dependency:tree排查冲突。
Q2:如何解决JSP页面EL表达式不生效?
A:在JSP页面顶部添加
<%@ page isELIgnored="false" %>,或在web.xml中配置<el-ignored>false</el-ignored>,Spring 5+默认开启EL表达式。
Q3:请求参数中文乱码怎么办?
A:配置CharacterEncodingFilter过滤器:
<filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter>
Q4:前后端分离项目是否还需要JSP?
A:不需要,前后端分离模式下,Controller返回JSON数据(使用
@RestController),前端通过Ajax或Fetch API调用接口展示,更推荐使用Vue/React配合Spring Boot进行开发。
Q5:本文案例中数据源使用的是内存Map,如何替换为真实数据库?
A:引入Spring JDBC或MyBatis依赖,配置DataSource(如使用HikariCP连接池+MySQL),将UserDao改为JdbcTemplate或MyBatis Mapper操作数据库表即可,注意添加事务管理注解
@Transactional。
实践建议: 当你完成本文案例后,推荐继续学习Spring Boot自动配置原理——它能帮你省去80%的手动配置工作,同时在项目中导入spring-boot-starter-web即可获得内嵌Tomcat和自动配置的DispatcherServlet。
本文所有代码在IntelliJ IDEA 2023.3 + Maven 3.9 + JDK 11 + Tomcat 9环境测试通过,实际部署时注意将数据库连接信息外置到配置文件中,如果使用阿里云或腾讯云服务器,建议使用
application.yml管理多环境配置。