Spring MVC(一)

1 Spring MVC概述

我们在之前学习Servlet的时候,认识了在WEB开发中MVC设计模式,其最为经典的设计就是,通过控制器(Controller)分离模型(Model)和视图(View)。在具体的WEB开发中,我们实现最多的功能就是页面的跳转和参数的传递。每次在使用Servlet进行操作的时候,都要手动的控制页面的跳转,开发效率非常低,虽然也可以使用一定的代码封装(BaseServlet),来简化操作,但是参数的传递只能频繁的使用getParameter方法来处理。鉴于以上问题,逐渐出现了一些自动化的MVC框架,其中Spring MVC就是目前非常优秀的MVC框架之一。

Spring MVC属于Spring Frame Work的后续产品,现已归属为Spring Web Flow里,Spring MVC是对传统的Servlet进行了一系列的封装。Spring MVC 分离了控制器、模型对象、过滤器以及处理程序对象的角色,这种分离让它们更容易进行定制。因此,在使用Spring MVC进行程序设计的时候,往往只需要编写少量的代码,就可以达到Servlet中复杂的实现。

Spring MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,使用了MVC架构模式的思想,将Web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发。

既然Spring MVC属于Spring的一部分,当然可以实现Spring到Spring MVC的无缝对接。在开发的时候,我们可以利用Spring的IOC容器来管理SpringMVC中所有的控制器,一个普通的POJO就可以被当做一个控制器来使用。Spring MVC提供了一个强大的中央控制器,我们可以通过该中央控制器轻松的实现页面跳转,同时可以利用Spring的注解,很方便的实现参数的传递。

2 Spring MVC项目环境搭建

既然Spring MVC是一个MVC框架,在开发的时候同样也需要导入相关的jar包。开发最基本的Spring MVC程序,需要导入的jar包有:

commons-logging-1.2.jar

spring-aop-4.3.9.RELEASE.jar

spring-beans-4.3.9.RELEASE.jar

spring-context-4.3.9.RELEASE.jar

spring-core-4.3.9.RELEASE.jar

spring-expression-4.3.9.RELEASE.jar

spring-web-4.3.9.RELEASE.jar

spring-webmvc-4.3.9.RELEASE.jar

创建一个web项目,我们暂时把项目名称命名为springmvc,然后拷贝上述jar包到项目的WebRoot/WEB-INF/lib目录中。项目的结构图如图所示。

上一节说过Spring MVC具有一个中央控制器,我们可以通过Spring MVC的中央控制器来轻松的完成对页面跳转和参数传递的控制。中央控制器如何才能得到利用呢,接下来需要在web.xml添加相应的配置,代码如下。

XML 复制代码
<servlet>
	<servlet-name>dispatcher</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
	<servlet-name>dispatcher</servlet-name>
	<url-pattern>/</url-pattern>
</servlet-mapping>

其中的<load-on-startup>配置的值为1,在学习Servlet的时候,我们知道,此处的配置意为在服务启动以后,立即加载该Servlet对象,因为Spring MVC中央控制器需要优先启动。其中的<url-pattern>配置的值为/,这样是为了拦截所有的URL请求。

在Spring MVC中,被中央控制器拦截的请求,全部交由一个统一的处理文件中,这个文件的位置必须在项目的WebRoot/WEB-INF目录下,名字必须是dispatcher-servlet.xml,因为我们在配置中央控制其的时候,指定的servlet-name是dispatcher,所以名字必须以servlet-name配置的名字开头。

其实,配置文件的名字和位置也是可以更改的,在web.xml文件中配置DispatcherServlet的时候,在其中的<servlet>配置中添加如下内容。

XML 复制代码
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>

这样一来,我们就可以在项目的src目录下创建配置文件了,文件的名字就可以指定为springmvc.xml。不过,在具体的开发过程中一般都是使用的默认值,也就是在WEB-INF目录下创建配置文件。

在WEN-INF目录下创建dispatcher-servlet.xml配置文件,并添加如下内容。

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
 
</beans>

通过之前Spring的学习,我们可以看到,其中的内容非常类似Spring的配置文件,这也意味着同样可以使用Spring IOC容器来管理对象。但是,在Spring MVC中管理的对象就是所有的控制器。接下来创建一个控制器HelloController,并编写以下代码。

java 复制代码
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

@Controller
public class HelloController extends AbstractController {
	@Override
	protected ModelAndView handleRequestInternal(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		System.out.println("Hello SpringMVC!!!");
		return new ModelAndView("/WEB-INF/jsp/hello.jsp");
	}
}

创建的控制器类HelloController继承了一个抽象类AbstractController,其实在Spring MVC中,所有的控制器完全可以不用继承任何类,这个在接下来的章节中会重点讲述,在此,先按照这种方式创建。

其实AbstractController类我们可以当做在创建Servlet的时候继承的HttpServlet。其中的handleRequestInternal方法我们可以当做Servlet中的doGet或者doPost方法,也就是所这个方法肯定会被自动调用。在方法中我们可以看到,传递了两个参数,这正是我们熟悉的HttpServletRequest对象和HttpServletResponse对象,这也就说明了我们编写的这个控制器,其根本也就是一个Servlet。handleRequestInternal方法的返回类型是ModelAndView,返回了一个ModelAndView对象,其中的参数为"/WEB-INF/jsp/hello.jsp",这正是我们熟悉的页面跳转,也就是返回的页面。此时我们应该在项目的WEB-INF目录下创建一个目录jsp,在其中创建一个hello.jsp文件,在<body>标签中添加相应的代码,具体内容如下。

html 复制代码
<body>
<br>
  <h1 align="center">Hello Spring MVC</h1>
  <br>
  <hr>
</body>

既然创建了一个控制器,这个控制器如何被Spring MVC所管理呢?之前提到过,Spring MVC可以使用Spring IOC容器来管理对象,我们就可以利用在dispatcher-servlet.xml文件中添加配置,代码如下。

XML 复制代码
<bean id="/hello" class="com.tedu.controller.HelloController" />

注意:此时配置的id的值为"/hello",这就是访问HelloController控制器的URL地址。把该项目部署到Tomcat中,启动服务就可以访问了。

在浏览其中输入地址http://localhost:8080/springmvc/hello 就可以访问项目了,具体的结果如图所示。

3 Spring MVC项目过程分析

Spring MVC项目执行的大致过程为:通过在浏览器中输入一个地址,首先这个地址请求资源的URL(在本例中就是/hello),会被在web.xml中配置的中央控制器拦截,然后交由dispatcher-servlet.xml文件处理,接下来会在该配置文件中查找id值为"/hello"的<bean>,然后到达指定控制器类,根据handleRequestInternal方法返回对象的参数,寻找到指定的视图页面。大致的执行过程,可以归纳为如图所示。

4 Spring MVC项目改进

在学习Spring的时候,我们在配置Spring IOC容器来管理对象的时候,推荐使用的是基于注解的操作,Spring MVC又是如何通过注解来操作呢?接下来把刚才的项目通过注解的形式重新改进一下,首先在dispatcher-servlet.xml文件中删除刚才的<bean>配置,并添加如下新的配置,以实现基于注解的操作。

XML 复制代码
<!-- 打开基于注解的操作 -->
<mvc:annotation-driven />
<!-- 到哪些包下扫描controller -->
<context:component-scan base-package="com.tedu.controller" />

此时的控制器HelloController就不需要再继承AbstractController类了,控制器HelloController要被Spring IOC容器管理,只需要在类上添加注解@Controller,通过Spring IOC容器来管理控制器,同时请求的地址可以在方法上通过注解@RequestMapping("/hello")来指定,具体的代码如下所示。

java 复制代码
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HelloController {
	@RequestMapping("/hello")
	public String hello() {
		System.out.println("Hello SpringMVC!!!");
		return "/WEB-INF/jsp/hello.jsp";
	}
}

通过以上操作,简化了控制器类的编写,控制器类可以不用继承任何类,也不用实现任何接口,就是一个POJO,却能到达同样的效果。

在本例中,控制器的操作方法返回的页面地址有点过于复杂,能不能通过简单的操作优化一下呢?接下来在dispatcher-servlet.xml文件添加如下配置。

XML 复制代码
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	<!-- 配置前缀和后缀映射 -->
	<property name="prefix" value="/WEB-INF/jsp/"></property>
	<property name="suffix" value=".jsp"></property>
</bean>

通过配置bean在Spring IOC容器中管理了InternalResourceViewResolver类的对象,用来对控制器类返回的URL地址进行重新编辑。在该类的父类中有一些属性,其中有"prefix"和"suffix",分别对应返回URL的前缀和后缀。通过<property>标签完成了对前缀和和后缀值的注入,当执行控制器中的方法后,会根据方法的返回值加上前缀和后缀,组成一个完整的URL地址。

因此方法的返回值就可以简化为"hello",dispatcher-servlet.xml配置文件会自动为其加上前缀"/WEB-INF/jsp/"和后缀".jsp",然后组成完整的返回地址。

相关推荐
V+zmm1013420 分钟前
基于微信小程序的乡村政务服务系统springboot+论文源码调试讲解
java·微信小程序·小程序·毕业设计·ssm
Oneforlove_twoforjob1 小时前
【Java基础面试题025】什么是Java的Integer缓存池?
java·开发语言·缓存
xmh-sxh-13141 小时前
常用的缓存技术都有哪些
java
AiFlutter1 小时前
Flutter-底部分享弹窗(showModalBottomSheet)
java·前端·flutter
J不A秃V头A2 小时前
IntelliJ IDEA中设置激活的profile
java·intellij-idea
DARLING Zero two♡2 小时前
【优选算法】Pointer-Slice:双指针的算法切片(下)
java·数据结构·c++·算法·leetcode
小池先生2 小时前
springboot启动不了 因一个spring-boot-starter-web底下的tomcat-embed-core依赖丢失
java·spring boot·后端
CodeClimb2 小时前
【华为OD-E卷-木板 100分(python、java、c++、js、c)】
java·javascript·c++·python·华为od
程序员厉飞雨2 小时前
Android R8 耗时优化
android·java·前端
odng2 小时前
IDEA自己常用的几个快捷方式(自己的习惯)
java·ide·intellij-idea