SSM之SpringMVC 01 —— SpringMVC原理及概念、Hello SpringMVC 注解版和配置版

系列文章

SSM之SpringMVC 01 —— SpringMVC原理及概念、Hello SpringMVC 注解版和配置版
SSM之SpringMVC 02 —— Controller和RestFul风格、转发和重定向、数据处理和乱码问题、Json
SSM之SpringMVC 03 —— 整合SSM(简单图书系统)
SSM之SpringMVC 04 —— Ajax、拦截器、文件上传和下载



1、回顾Servlet

在学习SpringMVC前需要先了解什么是MVC,这部分可以看我另一篇博客 JavaWeb 开发 04 —— JSP(原理、语法、指令、内置对象、JSP标签、JSTP标签)、JavaBean、MVC

同时,需要先回忆起Servlet,这里创建一个简单Servlet。

  1. 新建一个普通Maven项目,无需导入模板。

  2. 右键该项目,添加框架支持,并选择JavaWeb。

在这里插入图片描述

  1. 编写Servlet以及注册Servlet

HelloServlet.java

public class HelloServlet extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        //1. 获取前端参数
        String method = req.getParameter("method");
        if (method.equals("method1"))
            req.getSession().setAttribute("message", "执行了method1");
        else if (method.equals("method2"))
            req.getSession().setAttribute("message", "执行了method2");
        //2. 调用业务层
        //3. 视图转发或重定向
        req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        doGet(req, resp);
    }
}

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">
    
    <servlet>
        <servlet-name>helloServlet</servlet-name>
        <servlet-class>com.zcy.servlet.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>helloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>
  1. 编写jsp

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
    <form action="/hello" method="post">
      <input type="text" name="method">
      <input type="submit" value="提交"/>
    </form>
  </body>
</html>

test.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Test</title>
</head>
<body>
    ${message}
</body>
</html>
  1. 配置Tomcat并测试

在这里插入图片描述

在这里插入图片描述
 

2、SpringMVC

2.1、什么是SpringMVC

官方文档:https://docs.spring.io/spring-framework/docs/4.3.24.RELEASE/spring-framework-reference/html/mvc.html

SpringMVC是Spring Framework 的一部分,是基于Java实现MVC的轻量级Web架构。

SpringMVC的特点:

  • 轻量级,简单易学,简洁灵活
  • 高效,基于请求响应的MVC框架
  • 与Spring兼容性好,无缝结合
  • 约定大于配置
  • 功能强大:数据验证、格式化、本地化、主题等
  • 最重要的是使用的人多!

在这里插入图片描述

2.2 前端控制器

SpringMVC分为两个控制器,DispatcherServlet(前端控制器)和Controller(业务控制器)。由DispatcherServlet接收客户端请求,再根据客户端请求的URL的特点,分发到对应的Controller,比如UserController。

1614238445924

SpringMVC的原理如下图所示:
在这里插入图片描述
 

2.3、SpringMVC执行原理

图为SpringMVC的一个较完整的流程图,实线表示SpringMVC框架提供的技术,不需要开发者实现,虚线表示需要开发者实现 。

简要分析执行流程

在这里插入图片描述

  1. DispatcherServlet 表示前端控制器,是整个 SpringMVC 的控制中心。用户发出请求,会先被它接收并拦截。
    假设请求的URL为 : http://localhost:8080/HelloCtontroller/hello
    • http://localhost:8080 表示服务器域名
    • HelloCtontroller 表示部署在服务器上的web站点
    • hello 表示控制器
      该URL表示请求位于服务器localhost:8080上的HelloCtontroller站点的hello控制器。
  2. HandlerMapping 为处理映射器,当DispatcherServlet调用 HandlerMapping时,HandlerMapping会根据请求的URL找对应的实际处理器。
  3. HandlerExecution表示具体的处理器,它根据URL查找对应的控制器,如上URL被查找控制器为:hello。
  4. HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。
  5. HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler
  6. Handler让具体的Controller执行。
  7. Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView模型视图
  8. HandlerAdapter将视图名称或模型传递给DispatcherServlet
  9. DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名。
  10. 视图解析器将解析的逻辑视图名传给DispatcherServlet
  11. DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图。
  12. 最终视图呈现给用户。
     

3、Hello SpringMVC

对于配置版,先不用管具体原理,看看注释,然后照着代码写,正常执行一遍!再回过头去看看上面的原理。配置版主要是用于了解原理的。

可能碰到的问题:

1、运行时出现404:查看Artifacts中该模块是否包含lib目录以及各种包。

1614250800902

2、如果出现下面错误:是由于SpringMVC配置重复

在这里插入图片描述

解决方法:只保留一个就行。

在这里插入图片描述

3.1、配置版

一般开发不会这么写,比较麻烦,但执行原理是按照配置版来的。

1、新建一个Model

2、导入SpringMVC依赖

3、配置web.xml,注册 DispatcherServlet(这是依赖自带的)

<?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">

    <!-- 1. 注册DispatcherServlet    -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 关联一个springmvc的配置文件:springmvc-servlet.xml -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
        <!-- 启动级别 1  -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!-- 匹配所有请求,都用SpringMvc    -->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!-- 注意/*是包括了.jsp,而/是不包括.jsp -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

4、编写SpringMVC的配置文件:springmvc-servlet.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 添加官方的 处理映射器    -->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
    <!-- 添加官方的 处理适配器    -->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
    <!-- 添加官方的 视图解析器    -->

    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 下面的前后缀用于省略我们使用请求转发或者重定向时填写的路径,以后只需要写文件名 -->
        <!-- 前缀  -->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!-- 后缀  -->
        <property name="suffix" value=".jsp"/>
    </bean>

    <!-- 注册HelloController:通过向/hello发送请求,就会跳转到HelloController -->
    <bean id="/hello" class="com.zcy.controller.HelloController"/>
</beans>

5、编写Controller类(对比Servlet类)

package com.zcy.controller;

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

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloController implements Controller {
    
    
    public ModelAndView handleRequest(
            HttpServletRequest request, HttpServletResponse response
                                     ) throws Exception {
    
    
        //ModelAndView 代表模型和视图
        ModelAndView mv = new ModelAndView();
        String method = request.getParameter("method");

        //封装视图:把要跳转的新视图放在ModelAndView
        mv.setViewName("test");//因为我们在springmvc-servlet.xml配置了前缀和后缀

        if (method.equals("method1")){
    
    
            //封装对象:把数据放在ModelAndView,因为模型用于存放数据
            mv.addObject("message", "执行了method1");
        }
        else if (method.equals("method2")){
    
    
            mv.addObject("message", "执行了method2");
        }else{
    
    
            mv.addObject("message", "未执行method1和method2");
        }

        return mv;
    }
}

6、编写jsp页面:

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
  <title>$Title$</title>
</head>
<body>
<form action="/hello" method="post">
  <input type="text" name="method">
  <input type="submit" value="提交"/>
</form>
</body>
</html>

test.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Test</title>
</head>
<body>
    ${message}
    Hello SpringMVC
</body>
</html>

3.1、注解版

1、创建Maven Web项目

2、导入相关包

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.1.9.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.2</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>

</dependencies>

<!--在build中配置resources,来防止我们资源导出失败的问题-->
<build>
    <resources>
        <resource>
            <directory>${basedir}/src/main/webapp</directory>
        </resource>
        <resource>
            <directory>${basedir}/src/main/resources</directory>
        </resource>
        <resource>
            <directory>${basedir}/src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
                <include>**/*.properties</include>
            </includes>
        </resource>
    </resources>
</build>

2、编写web.xml,注册DispatcherServlet

<?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">

    <!--1.注册servlet-->
    <servlet>
        <servlet-name>SpringMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--通过初始化参数指定SpringMVC配置文件的位置,进行关联-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
        <!-- 启动顺序,数字越小,启动越早 -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!--所有请求都会被springmvc拦截 -->
    <servlet-mapping>
        <servlet-name>SpringMVC</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

3、编写SpringMVC配置文件springmvc-servlet.xml(其实就是Spring配置文件)

<?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"
       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
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 -->
    <context:component-scan base-package="com.zcy.controller"/>
    <!-- 让Spring MVC不处理静态资源 .css、.js等,以便提高效率 -->
    <mvc:default-servlet-handler />
    <!--
        支持mvc注解驱动
        在spring中一般采用@RequestMapping注解来完成映射关系
        要想使@RequestMapping注解生效
        必须向上下文中注册DefaultAnnotationHandlerMapping
        和一个AnnotationMethodHandlerAdapter实例
        这两个实例分别在类级别和方法级别处理。
        而annotation-driven配置帮助我们自动完成上述两个实例的注入。
    -->
    <mvc:annotation-driven />
    
    <!-- 视图解析器 -->
    <bean id="internalResourceViewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
        <!-- 前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/" />
        <!-- 后缀 -->
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

5、创建对应的控制类

package com.zcy.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@RequestMapping("/HelloController")
@Controller
public class HelloController {
    
    

    //真实访问地址:项目名/HelloController/hello
    @RequestMapping("/hello")
    public String hello(Model model) {
    
    
        //向模型添加msg属性,后面JSP页面通过${msg}读取
        model.addAttribute("msg", "Hello SpringMVC Annotation");
        //返回视图,由于配置文件写了前缀和后缀,所以只需要视图文件名
        return "hello";
    }
}
  • @Controller 是为了让Spring IOC容器初始化时自动扫描到;
  • @RequerstMapping 是为了映射请求路径,这里在类和方法上都有映射,所以是 /HelloController/hello ;
  • 方法中声明的Model类型就是模型,用于存储数据,能把数据带到视图去;
  • 方法返回的结果是视图的名称hello,就可以转发到hello.jsp

6、创建视图层

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
${msg}
</body>
</html>

8、运行Tomcat
在这里插入图片描述
 

小结

​ 使用SpringMVC 我们通常需要配置三个东西:处理器映射器、处理器适配器、视图解析器,其他就是控制类以及业务。但注解版可以帮我们省去映射器和适配器,极大简化开发过程。

猜你喜欢

转载自blog.csdn.net/qq_39763246/article/details/114164508