Spring MVC笔记

本文详细介绍了Spring MVC,一个主流的MVC框架,讲解了其核心组件如DispatcherServlet、HandlerMapping、HandlerAdapter等,以及工作流程。文章还涵盖了Spring MVC的注解使用、数据绑定、RESTful支持、文件上传下载、表单标签库、数据校验等内容,旨在帮助读者深入理解和应用Spring MVC。
摘要由CSDN通过智能技术生成

Spring MVC

Spring MVC 是目前主流的实现 MVC 设计模式的企业级开发框架,Spring 框架的一个子模块,无需整合,开发起来更加便捷。

什么是 MVC 设计模式?

将应用程序分为 Controller、Model、View 三层,Controller 接收客户端请求,调用 Model 生成业务数据,传递给 View。
在这里插入图片描述

Spring MVC 就是对这套流程的封装,屏蔽了很多底层代码,开放出接口,让开发者可以更加轻松、便捷地完成基于 MVC 模式的 Web 开发。

Spring MVC 的核心组件
  • DispatcherServlet:前置控制器,是整个流程控制的核心,控制其他组件的执行,进行统一调度,降低组件之间的耦合性,相当于总指挥。
  • Handler:处理器,完成具体的业务逻辑,相当于 Servlet 或 Action。
  • HandlerMapping:DispatcherServlet 接收到请求之后,通过 HandlerMapping 将不同的请求映射到不同的 Handler。
  • HandlerInterceptor:处理器拦截器,是一个接口,如果需要完成一些拦截处理,可以实现该接口。
  • HandlerExecutionChain:处理器执行链,包括两部分内容:Handler 和 HandlerInterceptor(系统会有一个默认的 HandlerInterceptor,如果需要额外设置拦截,可以添加拦截器)。
  • HandlerAdapter:处理器适配器,Handler 执行业务方法之前,需要进行一系列的操作,包括表单数据的验证、数据类型的转换、将表单数据封装到 JavaBean 等,这些操作都是由 HandlerApater 来完成,开发者只需将注意力集中业务逻辑的处理上,DispatcherServlet 通过 HandlerAdapter 执行不同的 Handler。
  • ModelAndView:装载了模型数据和视图信息,作为 Handler 的处理结果,返回给 DispatcherServlet。
  • ViewResolver:视图解析器,DispatcheServlet 通过它将逻辑视图解析为物理视图,最终将渲染结果响应给客户端。
Spring MVC 的工作流程
  • 客户端请求被 DisptacherServlet 接收。
  • 根据 HandlerMapping 映射到 Handler。
  • 生成 Handler 和 HandlerInterceptor。
  • Handler 和 HandlerInterceptor 以 HandlerExecutionChain 的形式一并返回给 DisptacherServlet。
  • DispatcherServlet 通过 HandlerAdapter 调用 Handler 的方法完成业务逻辑处理。
  • Handler 返回一个 ModelAndView 给 DispatcherServlet。
  • DispatcherServlet 将获取的 ModelAndView 对象传给 ViewResolver 视图解析器,将逻辑视图解析为物理视图 View。
  • ViewResovler 返回一个 View 给 DispatcherServlet。
  • DispatcherServlet 根据 View 进行视图渲染(将模型数据 Model 填充到视图 View 中)。
  • DispatcherServlet 将渲染后的结果响应给客户端。

在这里插入图片描述

Spring MVC 流程非常复杂,实际开发中很简单,因为大部分的组件不需要开发者创建、管理,只需要通过配置文件的方式完成配置即可,真正需要开发者进行处理的只有 Handler 、View。

如何使用?
  • 创建 Maven 工程,pom.xml
    (也是用的spring,spring-webmv是其中的一个小模块)
<dependencies>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.0.11.RELEASE</version>
    </dependency>

</dependencies>
  • 在 web.xml 中配置 DispatcherServlet。
    (servlet中配置dispathServlet,然后要导入springmvc.xml。mapping中配置 dispatcherServlet)
<!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>
  
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
  </servlet>
  
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
  
</web-app>
  • springmvc.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 http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">

    <!-- 自动扫描 -->
    <context:component-scan base-package="com.southwind"></context:component-scan>

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

</beans>

视图解析器:加个前缀/,加个后缀.jsp,假定文件名叫做index,结果就是/index.jsp。

  • 创建 Handler
package com.southwind.controller;

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

@Controller
public class HelloHandler {
   

    @RequestMapping("/index")
    public String index(){
   
        System.out.println("执行了index...");
        return "index";
    }
}

Spring MVC 注解

  • @RequestMapping

Spring MVC 通过 @RequestMapping 注解将 URL 请求与业务方法进行映射,在 Handler 的类定义处以及方法定义处都可以添加 @RequestMapping ,在类定义处添加,相当于客户端多了一层访问路径。

  • @Controller

@Controller 在类定义处添加,将该类交个 IoC 容器来管理(结合 springmvc.xml 的自动扫描配置使用!!!),同时使其成为一个控制器,可以接收客户端请求。

package com.southwind.controller;

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

@Controller
@RequestMapping("/hello")
public class HelloHandler {
   

    @RequestMapping("/index")
    public String index(){
   
        System.out.println("执行了index...");
        return "index";
    }
}
  • @RequestMapping 相关参数

1、value:指定 URL 请求的实际地址,是 @RequestMapping 的默认值。

@RequestMapping("/index")
public String index(){
   
    System.out.println("执行了index...");
    return "index";
}

等于

@RequestMapping(value="/index")
public String index(){
   
    System.out.println("执行了index...");
    return "index";
}

2、method:指定请求的 method 类型,GET、POST、PUT、DELET。(增删改查)

@RequestMapping(value = "/index",method = RequestMethod.GET)
public String index(){
   
    System.out.println("执行了index...");
    return "index";
}

上述代码表示 index 方法只能接收 GET 请求

3、params:指定请求中必须包含某些参数,否则无法调用该方法。

@RequestMapping(value = "/index",method = RequestMethod.GET,params = {
   "name","id=10"})
public String index(){
   
    System.out.println("执行了index...");
    return "index";
}

上述代码表示请求中必须包含 name 和 id 两个参数,同时 id 的值必须是 10。
输入http://localhost:8080/hello/index?name=zhangsan&id=10,可以正常访问
输入http://localhost:8080/hello/index?name=zhangsan&id=10会报错,说id不对什么的。
在这里插入图片描述

关于参数绑定,在形参列表中通过添加 @RequestParam 注解完成 HTTP 请求参数与业务方法形参的映射。(@RequestParam是用来解放命名的,如果实参和形参名字一致其实是可以不用这个注解的)

@RequestMapping(value = "/index",method = RequestMethod.GET,params = {
   "name","id=10"})
public String index(@RequestParam("name") String str,@RequestParam("id") int age){
   
    System.out.println(str);
    System.out.println(age);
    System.out.println("执行了index...");
    return "index";
}

上述代码表示将请求的参数 name 和 id 分别赋给了形参 str 和 age ,同时自动完成了数据类型转换,将 “10” 转为了 int 类型的 10,再赋给 age,这些工作都是由 HandlerAdapter 来完成的。

Spring MVC 也支持 RESTful 风格的 URL

传统类型:http://localhost:8080/hello/index?name=zhangsan&id=10

REST:http://localhost:8080/hello/index/zhangsan/10

@RequestMapping("/rest/{name}/{id}")
public String rest(@PathVariable("name") String name,@PathVariable("id") int id){
   
    System.out.println(name);
    System.out.println(id);
    return "index";
}

通过 @PathVariable 注解完成请求参数与形参的映射(在restful风格使用)。

  • 映射 Cookie

Spring MVC 通过映射可以直接在业务方法中获取 Cookie 的值。

@RequestMapping("/cookie")
public String cookie(@CookieValue(value = "JSESSIONID") String sessionId){
   
    System.out.println(sessionId);
    return "index";
}
  • 使用 JavaBean 绑定参数

Spring MVC 会根据请求参数名和 JavaBean 属性名进行自动匹配,自动为对象填充属性值,同时支持级联属性。(这段代码要是提交的数据格式不对,会报错。。。)

package com.southwind.entity;

import lombok.Data;

@Data
public class Address {
   
    private String value;
}
package com.southwind.entity;

import lombok.Data;

@Data
public class User {
   
    private long id;
    private String name;
    private Address address;
}
<%--
  Created by IntelliJ IDEA.
  User: southwind
  Date: 2019-03-13
  Time: 15:33
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form action="/hello/save" method="post">
        用户id:<input type="text" name="id"/><br/>
        用户名:<input type="text" name="name"/><br/>
        用户地址:<input type="text" name="address.value"/><br/>
        <input type="submit" value="注册"/>
    </form>
</body>
</html>
@RequestMapping(value = "/save",method = RequestMethod.POST)
public String save(User user){
   
    System.out.println(user);
    return "index";
}

如果出现中文乱码问题,只需在 web.xml 添加 Spring MVC 自带的过滤器即可。(复制就好,也不用管为啥)

<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

输出结果:
User(id=1, name=阿萨德, address=Address(value=科技路))

  • JSP 页面的转发(服务器调整)和重定向(客户端调整):

Spring MVC 默认是以转发的形式响应 JSP。

1、转发

@RequestMapping("/forward")
public String forward(){
   
    return "forward:/index.jsp";
    //        return "index";
}

return “forward:/index.jsp”; 先写 forward:表示转发,转发到哪?
index.jsp。
2、重定向

@RequestMapping("/redirect")
public String redirect(){
   
    return "redirect:/index.jsp";
}

return “redirect:/index.jsp”; 先写redirect:表示转发,转发到哪?
index.jsp。(地址栏会变的!)

Spring MVC 数据绑定

数据绑定:在后端的业务方法中直接获取客户端 HTTP 请求中的参数,将请求参数映射到业务方法的形参中,Spring MVC 中数据绑定的工作是由 HandlerAdapter 来完成的。

  • 基本数据类型
@RequestMapping("/baseType")
@ResponseBody
public String baseType(int id){
   
    return id+"";
}

@ResponseBody 表示 Spring MVC 会直接将业务方法的返回值响应给客户端,如果不加 @ResponseBody 注解,Spring MVC 会将业务方法的放回值传递给 DispatcherServlet,再由 DisptacherServlet 调用 ViewResolver 对返回值进行解析,映射到一个 JSP 资源。

  • 包装类
@RequestMapping("/packageType")
@ResponseBody
public String packageType(@RequestParam(value = "num",required = false,defaultValue = "0") Integer id){
   
    return id+"";
}

包装类可以接收 null,当 HTTP 请求没有参数时,使用包装类定义形参的数据类型,程序不会抛出异常。

@RequestParam

value = “num”:将 HTTP 请求中名为 num 的参数赋给形参 id。

requried:设置 num 是否为必填项,true 表示必填,false 表示非必填,可省略。

defaultValue = “0”:如果 HTTP 请求中没有 num 参数,默认值为0.

  • 数组
@RestController
@RequestMapping("/data")
public class DataBindHandler {
   
    @RequestMapping("/array")
    public String array(String[] name){
   
        String str = Arrays.toString(name);
        return str;
    }
}

@RestController 表示该控制器会直接将业务方法的返回值响应给客户端,不进行视图解析。(替换每一个方法前面写的@ResponseBody )(如果与@Controller同时存在,听RestController的)

@Controller 表示该控制器的每一个业务方法的返回值都会交给视图解析器进行解析,如果只需要将数据响应给客户端,而不需要进行视图解析,则需要在对应的业务方法定义处添加 @ResponseBody。

@RestController
@RequestMapping("/data")
public class DataBindHandler {
   
    @RequestMapping("/array")
    public String array(String[] name){
   
        String str = Arrays.toString(name);
        return str;
    }
}

等同于

@Controller
@RequestMapping("/data")
public class DataBindHandler {
   
    @RequestMapping("/array")
    @ResponseBody
    public String array(String[] name){
   
        String str = Arrays.toString(name);
        return str;
    }
}
  • List

Spring MVC 不支持 List 类型的直接转换,需要对 List 集合进行包装。

集合封装类

package com.southwind.entity;

import lombok.Data;

import java.util.List;

@Data
public class UserList {
   
    private List<User> users;
}

JSP

<%--
  Created by IntelliJ IDEA.
  User: southwind
  Date: 2019-03-14
  Time: 09:12
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form action="/data/list" method="post">
        用户1编号:<input type="text" name="users[0].id"/><br/>
        用户1名称:<input type="text" name="users[0].name"/><br/>
        用户2编号:<input type="text" name="users[1].id"/><br/>
        用户2名称:<input type="text" name="users[1].name"/><br/>
        用户3编号:<input type="text" name="users[2].id"/><br/>
        用户3名称:<input type="text" name="users[2].name"/><br/>
        <input type="submit" value="提交"/>
    </form>
</body>
</html>

业务方法

@RequestMapping
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值