SpringMVC-01: SpringMVC概述,创建web工程,SpringMVC执行流程,SpringMVC核心类和注解

SpringMVC-01

1. 什么是SpringMVC?

Spring MVC是Spring提供的一个实现了Web MVC设计模式的轻量级Web框架。它与Struts2框架一样,都属于MVC框架,但其使用和性能等方面比Struts2更加优异。

springmvc 封装了serlvlet,实现的功能和BaseServlet类似,所有的路径分发都是经过DispatcherServlet

Spring MVC具有以下特点:

  • 是Spring框架的一部分,可以方便的利用Spring所提供的其他功能。
  • 灵活性强,易于与其他框架集成。
  • 提供了一个前端控制器DispatcherServlet,使开发人员无需额外开发控制器对象。
  • 可自动绑定用户输入,并能正确的转换数据类型。
  • 内置了常见的校验器,可以校验用户输入。如果校验不能通过,那么就会重定向到输入表单。
  • 支持国际化。可以根据用户区域显示多国语言。
  • 支持多种视图技术。它支持JSP、Velocity和FreeMarker等视图技术。
  • 使用基于XML的配置文件,在编辑后,不需要重新编译应用程序。

2.创建springmvc javaweb工程

2.1创建maven-web 工程并引入依赖

<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <maven.compiler.source>1.7</maven.compiler.source>
  <maven.compiler.target>1.7</maven.compiler.target>
  <!--在当前pom 或者父类pom 中声明属性  -->
  <spirng.version>5.0.16.RELEASE</spirng.version>
</properties>
<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
  </dependency>
  <!--  添加 servlet 依赖 -->
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope>
  </dependency>
  <dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.1</version>
    <scope>provided</scope>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spirng.version}</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>${spirng.version}</version>
  </dependency>
  <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.6.12</version>
  </dependency>
  <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.6.12</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>${spirng.version}</version>
  </dependency>
</dependencies>

2.2创建java,resource文件夹,并标注

在这里插入图片描述

2.3配置web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <!--  声明 前端控制器 tomcat启动时 加载DispatcherServlet  -->
  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 为前端控制器 配置文件(spring)-->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <!--
      配置文件名可以为  servlet-name + ‘-’+servlet.xml 名字
      此时使规范的名字,可以不用明确声明 初始化配置文件  可以不写出事参数contextConfigLocation
       如果不规范 必须写明    要求 规范 + 明写
      -->
      <param-value>classpath:springmvc-servlet.xml</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <!--
       localhost:8080/工程名/User/findUserById?id=1
       / 就是tomcat会根据 前端请求的路径 去访问相应的servlet 或者 资源文件 如果找到就访问,找不到就访问当前的 springmvc 对应的servlet
        找不到对应的路径的 servlet 时才匹配  现在 /  springmvc的servlet
   -->
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

2.4创建配置文件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"
       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">
    <!-- 开启包扫描器-->
    <context:component-scan base-package="com.yth"></context:component-scan>
    <!-- 开启 注解的控制器@Controller   -->
    <mvc:annotation-driven></mvc:annotation-driven>
    <!-- 声明 helloController
     为当前的HelloController 控制类配置 路径
     控制器 控制界面的跳转 返回前端数据 等同于servlet
     name 1.是在容器种 bean 的标识  name 还是一个url 路径 /helloController
    -->
    <bean class="com.yth.controller.HelloController" name="/helloController"></bean>
    <!-- 以下三个  bean 我们不明写入容器 则容器将以下类型的bean自动加入到容器中-->

    <!--
        声明在容器种加入 处理器映射器:  DispatcherServlet可以根据url 找到对应的处理
        就是一个map  key 就是url   value 就是处理器
                     /HelloController    HelloController.handleRequest  处理器
                     "/HiController//hi    public ModelAndView hi()      处理器
                     url 组成是由 控制器路径 + 处理器路径
    -->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
    <!--  处理器适配器
          充手机的插排 就是适配器 解决的是 充电接口不匹配
          ControllerHandlerAdapter 根据不同类型的处理器  选择调用处理器
          插排   可以驱动 手机两插口 也可以驱动  电脑三插口
    -->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
    <!--  视图解析器  将处理器返回的 ModelAndView 进行解析 渲染视图  转换为html网页
           找到对应 jsp ,并将数据给到 jsp   -->
    <bean class="org.springframework.web.servlet.view.InternalResorceViewResolver"></bean>
</beans>

2.5创建控制类

package com.yth.controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 创建一个类 实现 Controller 中的方法 handleRequest
 * @author yth
 * @date 2020/10/22 - 14:31
 */
public class HelloController implements Controller {
    
    

    @Override// 处理器  处理前端请求的数据
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
    
    
        // ModelAndView 封装了 数据 和 视图(jsp 的路径)
        ModelAndView modelAndView = new ModelAndView();
        // 设置视图路径 jsp 路径
        modelAndView.setViewName("/jsp/hello.jsp");
        //等价于 向 request 中写入属性
        modelAndView.addObject("msg","你好");
        // 返回数据 和 视图 的一个封装
        return modelAndView;
    }
}

2.6在web目录侠创建/jsp/hello.jsp

<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2020/10/22
  Time: 14:35
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>hello springmvc</h1>
<h3>${msg}</h3>
</body>
</html>

2.7开启tomcat,测试

3.SpringMVC执行流程

在这里插入图片描述

1、用户发送请求至前端控制器DispatcherServlet。

2、DispatcherServlet收到请求调用HandlerMapping处理器映射器。

3、处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。

4、 DispatcherServlet调用HandlerAdapter处理器适配器。

5、HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。

6、Controller执行完成返回ModelAndView。

7、HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。

8、DispatcherServlet将ModelAndView传给ViewReslover视图解析器。

9、ViewReslover解析后返回具体View.

10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。

11、DispatcherServlet响应用户。

4.SpringMVC核心类和注解

4.1DispatcherServlet

DispatcherServlet的全名是org.springframework.web.servlet.DispatcherServlet,它在程序中充当着前端控制器的角色。作用就是分发url,找到对应控制器,去处理对应的请求,当前前端访问的路径找不到对的servlet 的路径时,就去DispatcherServlet 配置的路径下去找

http://localhost:8080/HelloController

1.首先找/HelloController Servelt 没有

2.进入DispatcherServlet ,根据/HelloController 去找对应的 处理器

3.找到处理器HelloController的handleRequest 实现 Controller

5.调用 HelloController 中的handleRequest 去处理前端的请求

在使用时,只需将其配置在项目的web.xml文件中,其配置代码如下:

 <!--  声明 前端控制器 tomcat启动时 加载DispatcherServlet  -->
  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 为前端控制器 配置文件(spring)-->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <!--
      配置文件名可以为  servlet-name + ‘-’+servlet.xml 名字
      此时使规范的名字,可以不用明确声明 初始化配置文件  可以不写出事参数contextConfigLocation
       如果不规范 必须写明    要求 规范 + 明写
      -->
      <param-value>classpath:springmvc-servlet.xml</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <!--
       localhost:8080/工程名/User/findUserById?id=1
       / 就是tomcat会根据 前端请求的路径 去访问相应的servlet 或者 资源文件 如果找到就访问,找不到就访问当前的 springmvc 对应的servlet
        找不到对应的路径的 servlet 时才匹配  现在 /  springmvc的servlet
   -->
    <url-pattern>/</url-pattern>
  </servlet-mapping>

4.2@Controller注解

org.springframework.stereotype.Controller注解类型用于指示Spring类的实例是一个控制器,其注解形式为@Controller。该注解在使用时不需要再实现Controller接口,只需要将@Controller注解加入到控制器类上,然后通过Spring的扫描机制找到标注了该注解的控制器即可。

1.将当前对象标记加入到容器

2.标记当前类是一个控制器

@Controller
public class FirstController {
    
    
    @RequestMapping(value = "/first",method = RequestMethod.GET)
    public ModelAndView first(){
    
    
        // 数据 和  view 的封装
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("msg","first");

        modelAndView.setViewName("jsp/hello.jsp");
        return modelAndView;
    }
}

注意扫描必须配置

   <!--
        使用注解开发springmvc web
    -->
    <!--开启包扫描器 让contrller生成 bean  -->
    <context:component-scan base-package="com.wgz.spring.controller"/>
    <!--开启 url注解 绑定 handler 和 url -->
    <mvc:annotation-driven />

<mvc:annotation-driven />主要做用

启用后,Spring会默认帮我们注册处理请求,参数和返回值的类。,其中最主要的两个类:DefaultAnnotationHandlerMapping 和 AnnotationMethodHandlerAdapter

4.3@RequestMapping

可以标记方法上,也标记在类上 当时都是控制器内(需要和@Controller)

标记在类上面

为当前控制器配置路径,控制下面所有处理器 的url 都要加上当前 控制器路径

@Controller // 标记当前类是一个控制
@RequestMapping("/HiController")
public class HiController {

标记在方法:将当前方法作为为处理以 key:value形式放置到处理器映射其中

       // key: 控制器路径 + 处理器路径 :/HiController//hi
       // value: 当前处理器 方法
package com.yth.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
/**
 * @author yth
 * @date 2020/10/22 - 17:07
 */
@Controller
@RequestMapping("/HiController")
public class HiController {
    
    
    @RequestMapping("/hi")
    public ModelAndView hi(){
    
    
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("/jsp/hello.jsp");
        modelAndView.addObject("msg","你好");
        return modelAndView;
    }
    //(path = {"hi1","hi2"}  一个处理器可以配置多个路径
    //method = RequestMethod.POST 标记当前处理器 只处理 post 请求 
    //浏览器浏览则报405请求方法错误
    @RequestMapping(path = {
    
    "hi1","hi2"},method = RequestMethod.POST)
    public ModelAndView he(){
    
    
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("/jsp/hello.jsp");
        modelAndView.addObject("msg","你好");
        return modelAndView;
    }
}

4.4组合注解

Spring框架的4.3版本中,引入了新的组合注解,来帮助简化常用的HTTP方法的映射,并更好的表达被注解方法的语义。

  • @GetMapping:匹配GET方式的请求;
  • @PostMapping:匹配POST方式的请求;
  • @PutMapping:匹配PUT方式的请求;
  • @DeleteMapping:匹配DELETE方式的请求;
  • @PatchMapping:匹配PATCH方式的请求。
package com.yth.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
/**
 * @author yth
 * @date 2020/10/22 - 19:15
 */
@Controller
@RequestMapping("/FirstController")
public class FirstController {
    
    
    // 当前方法只让 get 访问
    // @RequestMapping(value = "/first",method = RequestMethod.GET)
    @GetMapping("/first1")  // 等价于  @RequestMapping(value = "/first",method = RequestMethod.GET)
    public ModelAndView h1(){
    
    
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("/jsp/hello.jsp");
        modelAndView.addObject("msg","你好");
        return modelAndView;
    }
    // 只接受 post 方式
    // @RequestMapping(value = "/first2",method = RequestMethod.POST)
    @PostMapping("/first2") // 等价于  @RequestMapping(value = "/first2",method = RequestMethod.POST)
    public ModelAndView h2(){
    
    
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("/jsp/hello.jsp");
        modelAndView.addObject("msg","你好");
        return modelAndView;
    }
}

4.5请求处理方法自带的参数和返回类型

在控制器类中,每一个请求处理方法都可以有多个不同类型的参数,以及一个多种类型的返回结果。在请求处理方法中,可以出现的参数类型如下:

javax.servlet.ServletRequest javax.servlet.http.HttpServletRequest

javax.servlet.ServletResponse javax.servlet.http.HttpServletResponse

javax.servlet.http.HttpSession java.util.Map

org.springframework.ui.Model org.springframework.ui.ModelMap

返回值类型:

ModelAndView 可以添加Model数据,并指定视图

String 返回jsp视图地址 最为常用

void 在异步请求时使用,它只返回数据,而不会跳转视图

package com.yth.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Map;

/**
 * @author yth
 * @date 2020/10/22 - 20:15
 */
@Controller
@RequestMapping("/Controller")
public class SecondController {
    
    
    @GetMapping("/second1")
    public ModelAndView second1(HttpServletRequest request, HttpSession session){
    
    
        ModelAndView modelAndView = new ModelAndView();
        //等价于  modelAndView.addObject("msg","session:"+session.getId())
        request.setAttribute("msg","session:"+session.getId());
        modelAndView.setViewName("/jsp/hello.jsp");
        return modelAndView;
    }
    /**
     * 返回值 是String  InternalResourceViewResolver 把字符串当成 jsp 路径解析
     * @return
     */
    @GetMapping("/second2")
    public String second2(HttpServletRequest request, ModelMap modelMap ,Model model, Map map,HttpSession session){
    
    
        // 向 model 中添加属性 等价与 向 httpServletRequest 添加
        // model.addAttribute("msg","来自model---session:"+session.getId());
        //  向modelMap
        modelMap.addAttribute("msg","session```:"+session.getId());
        return "/jsp/hello.jsp";// InternalResourceViewResolver 可以解析ModelAndView 还可以解析 字符串 字符串作为jsp 路径去解析
    
    @GetMapping("/second3")
    public void second3(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
        request.setAttribute("msg","request");
        //转发
        //request.getRequestDispatcher("/jsp/hello.jsp").forward(request, response);
        //重定向
        response.sendRedirect("/jsp/hello.jsp");
    }
}

4.6ViewResolver视图解析器

视图解析器的目的就是帮助我们简化view的路径,为我们自动补全jsp的路径

Spring MVC中的视图解析器负责解析视图。可以通过在配置文件springmvc-servlet.xml中定义一个ViewResolver来配置视图解析器,其配置示例如下:

 		<!-- 视图解析器 -->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
           <property name="prefix" value="/jsp/"></property> <!--前缀-->
           <property name="suffix" value=".jsp"></property>  <!--后缀-->
        </bean>

猜你喜欢

转载自blog.csdn.net/qq_41520945/article/details/109230592