本文还有配套的精品资源,点击获取
简介:本文详细介绍了如何使用SpringMVC框架构建一个具有登录功能的Web应用程序。文章探讨了SpringMVC的核心功能,事务管理的重要性,SpringJDBC在数据库操作中的应用,以及Junit在单元测试中的作用。实例中包含了一个Web应用必需的库文件和数据库脚本,强调了MyEclipse作为IDE的便利性。通过本实例,读者可以深入了解SpringMVC框架及其在Web开发中的应用。
SpringMVC是Spring框架的一部分,用于构建Web应用程序。它遵循MVC(Model-View-Controller)设计模式,通过分离业务逻辑层和用户界面层,实现了灵活和松耦合的应用程序结构。它简化了基于Java的Web应用程序开发,具有强大的功能和极佳的可扩展性。
SpringMVC由多个核心组件组成,主要包括DispatcherServlet、HandlerMapping、Controller、Model和View。 DispatcherServlet
作为SpringMVC的前端控制器,负责请求分发。 HandlerMapping
用于将请求映射到处理程序。 Controller
处理用户请求,并返回模型和视图。 Model
是数据模型,它作为控制器与视图之间的数据传递对象。 View
负责渲染模型数据,最终生成用户界面。
当一个用户发起请求时,请求首先被 DispatcherServlet
接收,该Servlet随后根据配置的 HandlerMapping
来寻找对应的 Controller
处理程序。 Controller
处理请求后,将数据填充到 Model
中,并返回一个逻辑视图名。 DispatcherServlet
接着找到对应的 View
, View
进行渲染,最后将结果显示给用户。
// 控制器示例代码
@Controller
public class HelloController {
@RequestMapping("/hello")
public String handleRequest(Model model) {
model.addAttribute("message", "Hello, SpringMVC!");
return "hello"; // 返回的逻辑视图名
}
}
SpringMVC的优势在于其轻量级、高效、松耦合和可扩展性,非常适合需要高度可定制的Web应用程序开发。它通过约定优于配置的原则简化了配置流程,易于集成RESTful API,并且与Spring框架的其他模块紧密集成,提供了一个强大的后端支持。
SpringMVC的典型应用场景包括构建RESTful Web服务,开发企业级应用中的Web层,以及替换传统Struts2框架的应用场景。由于其强大的社区支持和广泛的应用,SpringMVC已成为Java Web开发者的首选框架之一。
事务是数据库管理系统执行过程中的一个逻辑单位,由一个有限的操作序列构成,这些操作要么全部完成,要么全部不做,是一个不可分割的工作单位。事务具有四个基本属性,被称为ACID原则:
Spring框架提供了声明式事务管理与编程式事务管理两种方式:
PlatformTransactionManager
接口以及 TransactionTemplate
类来实现编程式事务管理。 // 使用TransactionTemplate进行编程式事务管理的简单示例
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
// 业务逻辑代码
}
});
用户认证是指验证用户是否是其所声明的人,即验证用户的合法性。用户认证通常包括以下步骤:
graph LR
A[开始] --> B[用户提交认证信息]
B --> C[验证信息]
C -->|成功| D[创建会话和认证令牌]
C -->|失败| E[返回错误]
D --> F[用户使用令牌访问资源]
访问控制是防止未授权访问受保护资源的过程。基于角色的访问控制(RBAC)是一种常用的访问控制方法,它根据用户的角色分配访问权限。
在Spring中配置事务管理器,以使用声明式事务管理:
在服务层标注事务管理的注解,控制事务的行为:
@Service
public class UserService {
@Autowired
private UserDAO userDAO;
@Transactional
public User login(String username, String password) {
// 验证用户信息
User user = userDAO.findByUsername(username);
if (user != null && user.getPassword().equals(password)) {
return user; // 登录成功
}
throw new AuthenticationException("Authentication failed.");
}
}
在实际的应用场景中,用户认证往往涉及到多个步骤,这些步骤需要被事务管理所包裹,确保整个过程的原子性。例如,用户登录成功后可能需要创建会话,更新最后登录时间等:
@Transactional
public User login(String username, String password) {
// 验证用户信息
User user = userDAO.findByUsername(username);
if (user != null && user.getPassword().equals(password)) {
// 创建会话
Session session = sessionDAO.create(user);
// 更新用户最后登录时间
userDAO.updateLastLoginTime(user);
return user; // 登录成功
}
throw new AuthenticationException("Authentication failed.");
}
在上述代码中,如果任何一个操作失败,所有操作将会回滚,保证了事务的原子性。使用Spring的声明式事务管理,业务开发人员无需手动编写回滚代码,极大地简化了代码的复杂性并提高了开发效率。
SpringJDBC是一种轻量级的框架,用于简化Java数据库连接(JDBC)操作。它提供了一种比传统JDBC更高级别的抽象,目的是简化常见的数据库操作,同时保留底层JDBC API的全部功能。SpringJDBC与原始JDBC相比,减少了大量样板代码,如资源管理、异常处理和事务管理。它支持声明式事务管理,这意味着开发者可以将事务管理代码从核心业务逻辑中分离出来。此外,SpringJDBC为开发者提供了更加简洁、清晰的编程模型,极大地提高了开发效率。
SpringJDBC的核心API主要包括以下几个主要组件:
JdbcTemplate
: 用于执行SQL语句,是SpringJDBC中最核心的类。它提供了许多便捷的方法,如 query
、 update
等,用于执行数据库操作。 NamedParameterJdbcTemplate
: 扩展了 JdbcTemplate
,支持命名参数,使得SQL语句的维护更加方便。 SimpleJdbcInsert
和 SimpleJdbcCall
: 分别用于批量插入数据和调用存储过程或函数。 DataSource
: 数据源接口,用于获取数据库连接,SpringJDBC支持多种数据源的实现。 在使用SpringJDBC时,通常首先配置数据源,然后注入 JdbcTemplate
到服务层中,就可以进行数据库操作了。
DAO(Data Access Object)设计模式是J2EE应用程序中用于分离数据访问逻辑和业务逻辑的一种常用方法。通过DAO模式,业务逻辑层与数据访问层分离,使得业务逻辑层无需了解底层数据访问的实现细节。DAO模式通常包含以下几个核心组件:
实现自定义的DAO类通常需要遵循以下步骤:
JdbcTemplate
等SpringJDBC组件。 下面是一个简单的DAO实现示例:
public interface UserDao {
User getUserById(int id);
}
@Component
public class UserDaoImpl implements UserDao {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public User getUserById(int id) {
String sql = "SELECT * FROM users WHERE id = ?";
return jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(User.class), id);
}
}
在上述示例中, UserDao
定义了获取用户信息的方法, UserDaoImpl
类实现了该接口并注入了 JdbcTemplate
实例。使用 queryForObject
方法执行了一个简单的SQL查询,并将结果映射到一个 User
对象中。
在SpringMVC应用程序中集成SpringJDBC通常涉及配置数据源和事务管理器,以便于进行数据库操作和事务控制。下面是一个Spring配置示例:
在这个配置中,我们定义了数据源、 JdbcTemplate
和事务管理器。通过
标签,我们启用了注解驱动的事务管理。
一旦数据源、 JdbcTemplate
和事务管理器配置完成,我们就可以创建和测试DAO层组件。通常这会涉及到以下几个步骤:
以下是一个服务层类的实现,该类通过调用 UserDaoImpl
类中的方法来获取用户信息:
@Service
public class UserService {
private final UserDao userDao;
@Autowired
public UserService(UserDao userDao) {
this.userDao = userDao;
}
public User getUserById(int id) {
return userDao.getUserById(id);
}
}
为了测试该服务层,我们可以使用JUnit和Spring的测试支持:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/applicationContext.xml"})
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
public void testGetUserById() {
User user = userService.getUserById(1);
assertNotNull(user);
// 断言更多用户信息
}
}
在这个测试用例中,我们首先使用 @RunWith
和 @ContextConfiguration
注解指定测试环境配置,然后通过 @Autowired
注解注入 UserService
。通过调用 getUserById
方法并验证返回的 User
对象是否符合预期来进行测试。
在现代软件开发中,单元测试已成为保证代码质量不可或缺的一环。单元测试专注于检查软件中最小可测试的部分,通常是一个函数或方法,以确保每个部分都能按预期工作。这种测试的目的是为了尽早发现并修复缺陷,降低集成阶段或最终用户发现问题的风险。单元测试还有助于开发者理解代码逻辑,为重构提供信心,并加快开发速度。此外,良好的单元测试覆盖率可以作为代码质量的直接指标,引导团队追求更高的代码标准。
单元测试还能提高软件设计的质量。在编写测试用例的过程中,开发者往往会意识到设计上的问题,从而有机会提前解决它们。更重要的是,拥有良好单元测试覆盖的代码库,可以让未来的开发工作更加轻松,因为开发者可以更安全地修改现有代码。
Junit是一个广泛使用的Java单元测试框架。它支持测试驱动开发(TDD),使得编写测试代码和实现代码几乎可以并行进行。Junit框架利用注解来标记测试方法和配置测试环境,最常用的注解包括:
@Test
: 标记一个方法为测试方法。 @Before
: 每个测试方法执行之前运行,用于初始化环境。 @After
: 每个测试方法执行之后运行,用于清理环境。 @BeforeClass
: 仅在类中的所有测试开始前运行一次,通常用于静态资源的初始化。 @AfterClass
: 仅在类中的所有测试结束之后运行一次,通常用于静态资源的清理。 @Ignore
: 标记测试方法为忽略状态,Junit将不执行此测试。 import org.junit.*;
public class ExampleTest {
@BeforeClass
public static void setUpClass() {
// 初始化代码
}
@AfterClass
public static void tearDownClass() {
// 清理代码
}
@Before
public void setUp() {
// 每个测试前运行的代码
}
@After
public void tearDown() {
// 每个测试后运行的代码
}
@Test
public void testExample() {
// 测试代码
}
}
让我们通过一个简单的测试用例来演示如何使用Junit进行单元测试。假设有一个 Calculator
类,我们需要验证其 add
方法的功能正确性。
public class Calculator {
public int add(int a, int b) {
return a + b;
}
}
下面是使用Junit进行 add
方法的测试用例:
import static org.junit.Assert.assertEquals;
public class CalculatorTest {
private Calculator calculator;
@Before
public void setUp() {
calculator = new Calculator();
}
@Test
public void testAdd() {
assertEquals("1 + 1 should be 2", 2, calculator.add(1, 1));
assertEquals("0 + 1 should be 1", 1, calculator.add(0, 1));
}
@Test
public void testAddWithNegativeNumbers() {
assertEquals("-1 + 1 should be 0", 0, calculator.add(-1, 1));
assertEquals("-1 + -1 should be -2", -2, calculator.add(-1, -1));
}
}
在测试方法中,我们使用 assertEquals
来断言两个值是否相等。如果测试失败,Junit将报告失败并提供预期值和实际值的信息,这将极大地帮助开发者快速定位问题所在。
为了测试SpringMVC应用,Spring提供了 Spring TestContext Framework
,它允许开发者在Spring的测试支持下进行测试。这个框架提供了针对Spring环境的上下文管理、依赖注入以及自动化的事务管理等,使得测试可以在模拟的环境里执行。Spring MVC Test提供了一套模拟的测试类,比如 MockMvc
,它可以帮助我们模拟发送请求和接收响应,而不需要真正启动服务器。
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = MyController.class)
public class MyControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
public void testHomePage() throws Exception {
mockMvc.perform(get("/"))
.andExpect(status().isOk())
.andExpect(view().name("index"));
}
}
在Spring MVC中,测试控制器通常需要几个步骤:创建测试类,配置 @WebMvcTest
注解,注入 MockMvc
,以及编写测试方法。以下是一个测试控制器的示例:
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = MyController.class)
public class MyControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private MyService myService;
@Test
public void testHomePage() throws Exception {
when(myService.getMessage()).thenReturn("Hello, World!");
mockMvc.perform(get("/"))
.andExpect(status().isOk())
.andExpect(view().name("home"))
.andExpect(model().attribute("message", "Hello, World!"));
}
}
在此测试中,我们使用 @WebMvcTest
注解来指定测试类只针对MVC层,而 @MockBean
注解用来创建一个假的服务对象。我们还演示了如何使用 MockMvc
来模拟发送GET请求,并验证返回的状态码、视图名称以及模型属性。
测试执行后,Junit会自动生成测试结果,并通过图形化界面(如IntelliJ IDEA自带的测试视图)展示每个测试的状态。这包括成功、失败以及错误的测试。每个测试用例都有自己的执行时间,对于执行时间过长的测试用例,我们应当进行性能分析,看是否可以进行优化。
测试结果应该细致分析,找出失败的测试用例,查看失败原因。如果是断言失败,那么需要回到代码中找到问题所在。如果是错误(Exception),则需要在测试用例或被测试代码中进行调试。
代码覆盖率是一个衡量测试质量的重要指标。它显示了代码中被测试覆盖到的比例,常见的覆盖率指标包括行覆盖率、分支覆盖率等。提高覆盖率有助于确保代码中尽可能多的部分被测试覆盖,减少缺陷出现的概率。
要提高代码覆盖率,可以采取以下几个策略:
graph LR
A[开始测试覆盖率分析] --> B[运行测试]
B --> C{检查覆盖率报告}
C -->|低覆盖率| D[识别未覆盖代码]
C -->|高覆盖率| E[完成测试,记录结果]
D --> F[编写测试用例覆盖未测试区域]
F --> B
通过不断的迭代和优化测试用例,可以逐步提高代码覆盖率,进而提高软件的整体质量。
Apache Maven 是一个项目管理和自动化构建的工具,主要服务于Java平台的项目。它通过一个中央项目对象模型(POM)来描述项目的构建过程、依赖关系、报告、SCM、发布等信息。使用Maven可以帮助开发者轻松地进行项目的构建、文档生成、报告以及构建依赖管理。
Maven的基础配置通常包括以下几个步骤:
bin
目录路径,以便可以在命令行中直接使用 mvn
命令。 mvn archetype:generate
来创建一个标准的Maven项目结构。 pom.xml
文件:这是Maven的核心文件,它定义了项目的结构、构建配置、依赖关系等信息。需要配置项目的信息,如 groupId
、 artifactId
、 version
以及项目的打包方式等。
4.0.0
com.mycompany.app
my-app
1.0-SNAPSHOT
jar
my-app
http://maven.apache.org
groupId
、 artifactId
和 version
来唯一确定。当Maven执行构建时,它会自动下载项目依赖到本地仓库。 在 pom.xml
文件中,可以通过
标签来添加项目依赖。Maven会处理依赖的传递性,并解析依赖冲突。
junit
junit
4.12
test
在上面的例子中,我们添加了JUnit作为测试的依赖。
标签指定了依赖的作用范围,这里是 test
,意味着JUnit仅在测试阶段被使用。
管理库版本时,可以使用Maven的版本范围或属性的概念。版本范围允许灵活指定版本,而属性允许在多处共享和修改版本号,如:
5.2.0.RELEASE
org.springframework
spring-core
${spring.version}
在上述配置中,我们定义了一个版本属性
,然后在Spring核心库的依赖中使用它。这样,如果需要更改Spring的版本,只需要修改属性值即可,无需逐个修改每个依赖。
构建一个基于SpringMVC的Web应用,需要配置特定的依赖库。以下是一些典型的库文件配置示例:
org.springframework
spring-webmvc
${spring.version}
org.springframework
spring-context
${spring.version}
javax.servlet
javax.servlet-api
4.0.1
provided
javax.servlet
jstl
1.2
org.slf4j
slf4j-log4j12
1.7.30
在这些依赖中, spring-webmvc
和 spring-context
是构建SpringMVC Web应用不可或缺的部分。 javax.servlet-api
依赖虽然在编译时需要,但通常不需要打包到最终的WAR文件中,因此其作用范围被设置为 provided
。JSTL库用于JSP页面中显示数据,而SLF4J和log4j结合使用提供了日志记录功能。
在Web应用部署阶段,需要特别注意库文件的处理。理想情况下,应该避免将所有依赖库都打包到最终的WAR文件中,这样做可以减少WAR的大小并允许服务器共享相同的库文件。Maven可以配置为依赖外部库,这样在部署时就不需要将这些库打包。
通过设置 maven-war-plugin
插件的
选项,可以指定不打包的库文件:
org.apache.maven.plugins
maven-war-plugin
3.2.3
WEB-INF/lib/*.jar
上述配置确保在打包时, WEB-INF/lib
目录下的所有 .jar
文件都不会被包含到WAR文件中。
数据库脚本是用于创建数据库、表、存储过程、触发器等的脚本文件。编写高质量的数据库脚本可以确保数据库结构的一致性、可维护性和易于部署。以下是一些数据库脚本编写的基本规范:
create_users_table.sql
。 sql -- Version: 1.0 | Date: 2023-04-01
GO
(SQL Server)或 /
(Oracle),来明确脚本的结束。 编写数据库脚本时,可以考虑数据库的不同特性。例如,在使用MySQL时,可以使用以下脚本来创建一个用户表:
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(255) NOT NULL,
`email` varchar(100),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 插入初始数据示例
INSERT INTO `users` (`username`, `password`, `email`) VALUES ('admin', 'admin', '[email protected]');
数据库初始化脚本用于部署新应用或在测试环境中准备数据库。数据清理脚本则用于在测试或开发结束后清理数据,以避免数据污染。
一个初始化脚本可能包含创建数据库结构、插入初始数据和设置权限等操作。清理脚本应包含删除数据、重置数据和清理测试数据等操作。
例如,下面是一个简单的初始化脚本示例:
-- 创建数据库表
DROP TABLE IF EXISTS `logs`;
CREATE TABLE `logs` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`message` text,
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 插入测试数据
INSERT INTO `logs` (`message`) VALUES ('This is a test entry.');
-- 添加数据清理脚本
TRUNCATE TABLE `logs`;
注意,在执行初始化和清理操作时,应该在数据库管理员的指导下谨慎操作,以防止误操作导致数据丢失或安全问题。使用脚本文件时,可以通过命令行执行,或者使用数据库管理工具提供的执行功能来运行这些脚本。
这些脚本在版本控制系统的跟踪下,可以在不同的环境(开发、测试、生产)之间进行迁移,并确保每次迁移后的数据库状态都是一致的。
MyEclipse IDE,作为一款强大的Java开发工具,它提供了丰富的特性和插件,以支持开发人员高效地构建各种应用程序。对于那些期望在SpringMVC项目和其他Java EE开发中快速启动和运行的开发者而言,MyEclipse提供了一个全方位的集成解决方案。
MyEclipse的主要特点包括: - 可视化编辑器 :用于编辑多种配置文件,比如Spring、Struts和Hibernate配置文件。 - 代码辅助和编辑 :提供代码自动补全、代码重构、语法高亮、错误检测等功能。 - J2EE支持 :集成了对JSP、Servlet、EJB和JPA等Java EE标准的支持。 - Maven集成 :允许开发者通过Maven进行依赖管理和构建自动化。 - Web服务工具 :支持RESTful Web服务和SOAP Web服务的开发和测试。 - Mylyn集成 :提供任务管理和缺陷跟踪的集成。 - 数据库工具 :提供数据库访问和管理的图形化工具。
安装MyEclipse IDE是一个简单直接的过程。访问MyEclipse官网下载最新版安装包,并根据安装向导完成安装。
安装完成后,进行如下配置以适应开发需求: 1. 启动配置 :首次启动MyEclipse时,可以通过向导完成初始配置,包括设置工作空间、检查更新和配置Java运行环境。 2. 添加插件 :MyEclipse支持通过Eclipse Marketplace安装额外插件,以增强功能。 3. 调整偏好设置 :在Window->Preferences菜单下,开发者可以根据自己的习惯调整代码编辑、快捷键、字体大小和颜色主题等偏好设置。
创建SpringMVC项目可以通过MyEclipse的项目向导来完成,它会自动生成项目结构,并配置好必要的文件和依赖。
项目创建完成后,需要根据项目需求手动配置或调整项目结构及依赖管理。
MyEclipse提供高级的代码编辑和调试工具,开发者可以通过以下步骤进行优化配置:
为增强开发体验,安装和配置额外插件是优化MyEclipse IDE的重要步骤:
在进行了上述配置之后,MyEclipse IDE将为开发者提供一个功能强大且个性化的开发环境,从而提高开发效率并确保代码质量。
在构建一个SpringMVC登录Web应用时,首先需要对登录功能进行详细的需求分析。登录功能通常包括用户认证和授权机制,是大多数Web应用的基础。在此阶段,我们需要确定用户如何提交登录请求,以及服务器如何响应。需求分析应该包括以下几个关键点:
用户界面是用户与系统交互的前端部分。对于登录界面,我们需要设计一个简单的表单,包含用户名和密码输入字段,以及记住我选项和登录按钮。
用户名:
密码:
在业务逻辑层,我们将处理用户的登录请求。这通常涉及到用户信息的验证,以及在用户成功登录后设置会话信息。
// UserService.java
public class UserService {
public User login(String username, String password) {
// 这里应该查询数据库验证用户名和密码
// 以下代码仅为示例,实际应用中需要实现真正的认证逻辑
User user = userDAO.findByUsername(username);
if (user != null && user.getPassword().equals(password)) {
// 用户验证成功
return user;
}
return null;
}
}
数据访问层负责与数据库交互,执行查询操作来验证用户登录信息。
// UserDAO.java
public interface UserDAO {
User findByUsername(String username);
}
// UserDAOImpl.java
public class UserDAOImpl implements UserDAO {
public User findByUsername(String username) {
// 使用JDBC模板或者Hibernate Session来查询用户信息
// 这里仅返回一个示例用户对象
return new User(username, "hashedPassword");
}
}
为了保证登录过程的安全性,我们需要采用HTTPS来加密传输过程,防止数据被截获。同时,还需要防范跨站请求伪造(CSRF)攻击,可以通过添加CSRF令牌到表单来实现。
密码应该使用安全的方式存储,一般推荐使用哈希加盐(salt)的方式来存储密码哈希值。这样即使数据库被泄露,攻击者也无法直接获取用户密码。
// PasswordUtils.java
public class PasswordUtils {
public static String hashPassword(String password) {
// 使用BCrypt库来生成安全的哈希值
return BCrypt.hashpw(password, BCrypt.gensalt());
}
}
在应用开发过程中,单元测试和集成测试是非常重要的。单元测试关注单个组件的功能,而集成测试关注多个组件协同工作时的行为。
// UserServiceTest.java
public class UserServiceTest {
@Test
public void testLoginSuccess() {
UserService userService = new UserServiceImpl();
User user = userService.login("username", "password");
assertNotNull(user);
}
}
应用部署可以通过Maven或Gradle等构建工具自动化完成。部署后,还需要对应用进行监控,确保其稳定运行。
org.apache.maven.plugins
maven-deploy-plugin
通过构建一个SpringMVC登录Web应用的实战演练,我们不仅能够加深对SpringMVC框架的理解,还能够学习到如何保证Web应用的安全性和稳定性。
本文还有配套的精品资源,点击获取
简介:本文详细介绍了如何使用SpringMVC框架构建一个具有登录功能的Web应用程序。文章探讨了SpringMVC的核心功能,事务管理的重要性,SpringJDBC在数据库操作中的应用,以及Junit在单元测试中的作用。实例中包含了一个Web应用必需的库文件和数据库脚本,强调了MyEclipse作为IDE的便利性。通过本实例,读者可以深入了解SpringMVC框架及其在Web开发中的应用。
本文还有配套的精品资源,点击获取