Spring MVC 入门(二)第一个 Spring MVC 应用

第一个 Spring MVC 应用

MVC 概述

        MVC 是所有面向对象程序设计语言都应该遵守的规范。MVC思想将一个应用分为三个基本部分:Model(模型)、View(视图)和Controller(控制器),这三个部分以最少的耦合协同工作,从而提高应用的可扩展性及可维护性。
        在经典的 MVC 模式中,事件由控制器处理,控制器根据时间的类型改变模型或视图,反之亦然。从设计模式的角度来看,MVC 思想非常类似于观察者模式,但其与观察者模式存在少许差别:在观察者模式下,观察者和被观察者可以是两个互相对等的对象;但是在 MVC 中,被观察者往往只是单纯的数据体,而观察者则是单纯的视图页面。

MVC 特点

    MVC 有如下特点:

  • 多个视图可以对应一个模型。按 MVC 设计模式,一个模型对应多个视图,可以减少代码的复制及代码的维护量,这样,一旦模型发生改变,也易于维护。
  • 模型返回的数据与显示逻辑分离。模型数据可以应用任何的显示技术。
  • 应用被分割为三层,这降低了各层之间的耦合,提供了应用的可扩展性。
  • 控制层的概念很有效,由于它把不同的模型和不同的视图组合在一起,完成不同的请求。因此,控制层可以说包含了用户请求权限的概念。
  • MVC 更符合软件工程化管理的精神。不同的层各司其职,每一层的组件具有相同的特征,这有利于通过工程化和工具化的方法产生管理程序代码。

    :经典的 MVC 思想与 Web 应用的 MVC 思想也存在一定的差别,引起差别的主要原因是因为 Web 应用是一种请求/响应模式下应用,对应请求/相应应用,如果用户不对应用发出请求,视图将无法主动更新自己。
遵循 MVC 模式的 Java Web 的运行流程

Spring MVC 的 DispatcherServlet

        Spring MVC 提供了一个名为 org.springframework.web.servlet.DispatcherServlet 的 Servlet 充当用于调度控制的前端控制器,所有的请求驱动都围绕这个 DispatcherServlet 来分派请求。
        DispatcherServlet 是一个 Servlet ( 它继承自 HttpServlet 基类),因此使用时需要把它配置在 Web 应用的部署描述符 web.xml 文件中,配置信息如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <context-param>
        <!-- contextConfigLocation 是参数名称,该参数的值包含 Spring 的配置文件路径 -->
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
        <!-- Servlet 的名称 -->
        <servlet-name>springmvc</servlet-name>
        <!-- Servlet 对应的 Java 类 -->
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 当前 Servlet 的参数信息 -->
        <init-param>
         	<!-- contextConfigLocation 是参数名称,该参数的值包含 SpringMVC 的配置文件路径 -->
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
        </init-param>
        <!-- 在Web应用启动时立即加载Servlet -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!-- Servlet映射声明 -->
    <servlet-mapping>
        <!-- 请求对应的Servlet的名称 -->
        <servlet-name>springmvc</servlet-name>
        <!-- 监听当前域的所有请求 -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

        以上代码配置了一个 DispatcherServlet,该 Servlet 在 Web 应用程序启动时立即加载,DispatcherServlet 加载时会需要一个 Spring MVC 的配置文件,默认情况下,应用会去应用程序文件夹的 WEB-INF 下查找对应的 [servlet-name]-servlet.xml 文件。也可以把 Spring MVC 的配置文件放到应用程序文件夹中的任何地方,用 Servlet 元素的 init-param 子元素进行描述。
        解析 Spring MVC 的文件内容并根据文件配置信息创建一个 WebApplicationContext 容器对象,也成为上下文环境。WebApplicationContext 继承自 ApplicationContext 容器,因为 WebApplicationContext 需要 ServletContext 实例,也就是说,它必须在拥有 Web 容器的前提下才能完成启动 Spring Web 应用上下文的工作。有了 WebApplicationContext 容器,开发者就可以很自然地使用 Spring 的 IOC、AOP 等其他功能了。

基于 Controller 接口的控制器

        DispatcherServlet 在 Spring 当中充当一个前端控制器的角色,它的核心功能是分发请求。请求会被分发给对应处理的 Java 类,Spring MVC 中成为 Handle。在 Spring2.5 版本以前,开发一个 Handle 唯一方法就是实现 org.springframework.web.servlet.mvc.Controller 接口。Controller 接口必须实现一个方法,该方法的签名如下:

ModelAndView handleRequest(HttpServletRequest request,HttpServletResponse response) throws Exception

        Controller 接口的实现类只能处理一个单一请求动作,而 Spring2.5 之后新增的基于注解的控制器可以支持同时处理多个请求动作,并且无需实现任何接口,其更加灵活。

开发第一个Spring MVC 应用

1. 使用IntelliJ IDEA创建 SpringMVC 项目。
    启动IDEA后,点击 Create New Project。
在这里插入图片描述
    根据上图勾选后,点击 next。
在这里插入图片描述
    设置项目名为springmvc(项目位置自己设置,最好无中文)。然后点击 Finish。
在这里插入图片描述
    Spring MVC 工程创建完成,项目结构如上图。
2.配置前端控制器 DispatcherServlet
        修改 WEB-INF 目录下的 web.xml 文件。配置 Spring MVC 的前端控制器 DispatcherSerlvet。配置信息如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!--  定义 Spring MVC 的前端控制器  -->
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!--  让 Spring MVC 的前端控制器拦截所有请求  -->
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

    web.xml 文件的内容告诉 Web 容器 ,将使用 Spring MVC 的DispatcherServlet,并通过配置 url-pattern 元素的值为“/”,将所有的 URL 映射到该 Servlet。
3.配置 Spring MVC 的 Controller

    编辑 Spring MVC 配置文件,配置信息如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--   配置 Handle,映射 “/hello” 请求  -->
    <bean name="/hello" class="controller.HelloController"/>
    <!--  处理映射器将 bean 的 name 作为 url 进行查找,需要在配置 Handle 时指定name(即url)  -->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
    <!--  SimpleControllerHandlerAdapter 是一个处理器适配器,所有处理适配器都要实现 HandlerAdapter 接口  -->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
    <!--  视图解析器  -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"/>
</beans>

    dispatcher-servlet.xml 文件声明了 HelloController 业务控制器类,并将其映射到 /hello 请求。
    配置的处理器映射器 BeanNameUrlHandlerMapping 可以将 Bean 的名称作为 url 进行查找;配置的处理器适配器 SimpleControllerHandlerAdapter 完成对 HelloController 类的 handleRequest 方法的调用;最后配置的视图解析器 InternalResourceViewResolver 来解析视图,将 View 呈现给用户。
    在 Spring 4.0 之后,如果不配置处理器映射器、处理器适配器和视图解析器,也会使用默认的完成 Spring 内部的 MVC 工作。
4.Controller 类的实现
    HelloController 类实现了 Controller 接口,用来处理 /hello 请求。代码如下:

package controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

/*
* HelloController 是一个实现 Controller 接口的控制器,
* 可以处理一个单一的请求动作
*/
public class HelloController implements Controller {
    private static final Log logger = LogFactory.getLog(HelloController.class);

    /*
    * handleRequest 是 Controller 接口必须实现的方法。
    * 该方法的参数是对应请求的 HttpServletRequest 和 HttpServletResponse。
    * 该方法必须返回一个包含视图名或视图名和模型的 ModelAndView 对象。
    * */

    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        logger.info("handleRequest 被调用");
        //创建准备返回的 ModelAndView 对象,该对象通常包含了返回视图名、模型的名称以及模型对象
        ModelAndView mv = new ModelAndView();
        //添加模型数据,可以是任意的 POJO 对象
        mv.addObject("message","Hello World!");
        //设置逻辑视图名,视图解析器会根据改名字解析到具体的视图页面
        mv.setViewName("/WEB-INF/content/welcome.jsp");
        //返回 ModelAndView 对象。
        return mv;
    }
}

    如果遇到找不到 javax.serlvet 包的问题可以点击 File->Project Structure,点击 Modules 添加 Tomcat 依赖。
在这里插入图片描述
在这里插入图片描述
    Spring MVC建议把所有的视图页面存放在 WEB-INF文件夹下,这样可以保护视图页面,避免直接向视图页面发起请求。
5.View 页面
    项目包含一个视图页面 welcome.jsp ,用来显示欢迎信息。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>welcome</title>
</head>
<body>
    <!-- 页面可以访问 Controller 传递出来的 message -->
    ${ requestScope.message}
</body>
</html>

    此处使用El表达式来简化页面开发。
6.测试应用
    在浏览器中输入如下URL来测试应用:

http://localhost:8080/SpringMVC_war_exploded/hello

看到如下图所示界面,表示 Spring MVC 访问成功。
在这里插入图片描述

基于注解的控制器

    Spring 2.5 版本开始新增了可基于注解的控制器,也就是说控制器不用实现Controller接口,通过注释类型来描述。
    在springmvc项目基础上,修改两个地方:
1.Controller 类的实现
HelloController 类不需要 Controller 接口,改为使用注释类型来描述,用来处理 /hello 请求。代码如下:

package controller;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

/*
* HelloController 是一个基于注解的控制器,
* 可以同时处理多个请求动作,并且无需实现任何接口。
* org.springframework.stereotype.Controller 注解用于指示该类是一个控制器。
* */
@Controller
public class HelloController {

    private static final Log logger = LogFactory.getLog(HelloController.class);

    /*
    * org.springframework.web.bind.annotation.RequestMapping 注解
    * 用来映射请求与的 URL 和请求的方法等。
    * hello 只是一个普通方法。
    * 该方法返回一个包含视图名或视图名和模型的 ModelAndView 对象
    * */
    @RequestMapping(value = "/hello")
    public ModelAndView hello(){
        logger.info("hello方法 被调用");
        //创建准备返回的 ModelAndView 对象,该对象通常包含了返回视图名、模型的名称以及模型对象
        ModelAndView mv = new ModelAndView();
        //添加模型数据,可以是任意的 POJO 对象
        mv.addObject("message","Hello World!");
        //设置逻辑视图名,视图解析器会根据改名字解析到具体的视图页面
        mv.setViewName("/WEB_INF/content/welcome.jsp");
        return mv;
    }
}

2.修改 Spring MVC 的配置文件

<?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:context="http://www.springframework.org/schema/context"
       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">
    <!--  spring 可以自动去扫描 base-pack 下面的包或者子包下面的 Java 文件,
      如果扫描到有 Spring 的相关注解的类,则把这些类注册为 Spring 的 bean-->
    <context:component-scan base-package="controller"/>
    <!--  配置 annotation 类型的处理映射器  -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
    <!--  配置 annotation 类型的处理器适配器  -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
    <!--  视图解析器  -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"/>
</beans>

3.测试
    在浏览器中输入如下URL来测试应用:

http://localhost:8080/SpringMVC_war_exploded/hello

看到如下图所示界面,表示 Spring MVC 访问成功。
在这里插入图片描述

发布了6 篇原创文章 · 获赞 5 · 访问量 227

猜你喜欢

转载自blog.csdn.net/qq_41805741/article/details/103943834