SpringMVC从入门到精通

文章目录


三层架构介绍

在这里插入图片描述
Spring MVC 是 Spring 提供的一个基于 MVC 设计模式的轻量级 Web 开发框架,本质上相当于 Servlet。

Spring MVC 角色划分清晰,分工明细。由于 Spring MVC 本身就是 Spring 框架的一部分,可以说和 Spring 框架是无缝集成。性能方面具有先天的优越性,是当今业界最主流的 Web 开发框架,最热门的开发技能。

一个好的框架要减轻开发者处理复杂问题的负担,内部有良好的扩展,并且有一个支持它的强大用户群体,恰恰 Spring MVC 都做到了。

MVC设计模式简介

MVC 设计模式一般指 MVC 框架,M(Model)指数据模型层,V(View)指视图层,C(Controller)指控制层。使用 MVC 的目的是将 M 和 V 的实现代码分离,使同一个程序可以有不同的表现形式。其中,View 的定义比较清晰,就是用户界面。

在 Web 项目的开发中,能够及时、正确地响应用户的请求是非常重要的。用户在网页上单击一个 URL 路径,这对 Web 服务器来说,相当于用户发送了一个请求。而获取请求后如何解析用户的输入,并执行相关处理逻辑,最终跳转至正确的页面显示反馈结果,这些工作往往是控制层(Controller)来完成的。

在请求的过程中,用户的信息被封装在 User 实体类中,该实体类在 Web 项目中属于数据模型层(Model)。

在请求显示阶段,跳转的结果网页就属于视图层(View)。

像这样,控制层负责前台与后台的交互,数据模型层封装用户的输入/输出数据,视图层选择恰当的视图来显示最终的执行结果,这样的层次分明的软件开发和处理流程被称为 MVC 模式。

在学习 Servlet 及 JSP 开发时,JavaBean 相当于 Model,Servlet 相当于 Controller,JSP 相当于 View。

总结⚠️如下:
视图层(View):负责格式化数据并把它们呈现给用户,包括数据展示、用户交互、数据验证、界面设计等功能。
控制层(Controller):负责接收并转发请求,对请求进行处理后,指定视图并将响应结果发送给客户端。
数据模型层(Model):模型对象拥有最多的处理任务,是应用程序的主体部分,它负责数据逻辑(业务规则)的处理和实现数据操作(即在数据库中存取数据)。

SUN 公司推出 JSP 技术的同时,也推出了两种 Web 应用程序的开发模式。即 JSP+JavaBean 和 Servlet+JSP+JavaBean。

MVC优缺点

任何一件事都有利有弊,下面来了解一下 MVC 的优缺点。
优点

  • 多视图共享一个模型,大大提高了代码的可重用性
  • MVC 三个模块相互独立,松耦合架构
  • 控制器提高了应用程序的灵活性和可配置性
  • 有利于软件工程化管理

总之,我们通过 MVC 设计模式最终可以打造出一个松耦合+高可重用性+高可适用性的完美架构。
缺点

  • 原理复杂
  • 增加了系统结构和实现的复杂性
  • 视图对模型数据的低效率访问

MVC 并不适合小型甚至中型规模的项目,花费大量时间将 MVC 应用到规模并不是很大的应用程序,通常得不偿失,所以对于 MVC 设计模式的使用要根据具体的应用场景来决定。

Spring MVC是什么

Spring MVC 是 Spring 提供的一个基于 MVC 设计模式的轻量级 Web 开发框架,本质上相当于 Servlet。

Spring MVC 是结构最清晰的 Servlet+JSP+JavaBean 的实现,是一个典型的教科书式的 MVC 构架,不像 Struts 等其它框架都是变种或者不是完全基于 MVC 系统的框架。

Spring MVC 角色划分清晰,分工明细,并且和 Spring 框架无缝结合。Spring MVC 是当今业界最主流的 Web 开发框架,以及最热门的开发技能。

在 Spring MVC 框架中,Controller 替换 Servlet 来担负控制器的职责,用于接收请求,调用相应的 Model 进行处理,处理器完成业务处理后返回处理结果。Controller 调用相应的 View 并对处理结果进行视图渲染,最终客户端得到响应信息。

Spring MVC 框架采用松耦合可插拔的组件结构,具有高度可配置性,比起其它 MVC 框架更具有扩展性和灵活性。

Spring MVC优点

  • 清晰地角色划分,Spring MVC 在 Model、View 和 Controller 方面提供了一个非常清晰的角色划分,这 3 个方面真正是各司其职,各负其责。
  • 灵活的配置功能,可以把类当作 Bean 通过 XML 进行配置。
  • 提供了大量的控制器接口和实现类,开发者可以使用 Spring 提供的控制器实现类,也可以自己实现控制器接口。
  • 真正做到与 View 层的实现无关。它不会强制开发者使用 JSP,可以根据项目需求使用 Velocity、FreeMarker 等技术。
  • 国际化支持
  • 面向接口编程
  • 与 Spring 框架无缝集成

SpringMVC和Struts2的优劣分析

1.Spring MVC 基于方法开发,Struts2 基于类开发。
在使用 Spring MVC 框架进行开发时,会将 URL 请求路径与 Controller 类的某个方法进行绑定,请求参数作为该方法的形参。当用户请求该 URL 路径时, Spring MVC 会将 URL 信息与 Controller 类的某个方法进行映射,生成 Handler 对象,该对象中只包含了一个 method 方法。方法执行结束之后,形参数据也会被销毁。

而在使用 Struts2 框架进行开发时,Action 类中所有方法使用的请求参数都是 Action 类中的成员变量,随着方法变得越来越多,就很难分清楚 Action 中那么多的成员变量到底是给哪一个方法使用的,整个 Action 类会变得十分混乱。

相比较而言,Spring MVC 优点是其所有请求参数都会被定义为相应方法的形参,用户在网页上的请求路径会被映射到 Controller 类对应的方法上,此时请求参数会注入到对应方法的形参上。Spring MVC 的这种开发方式类似于 Service 开发。

2.Spring MVC 可以进行单例开发,Struts2 无法使用单例

Spring MVC 支持单例开发模式,而 Struts2 由于只能通过类的成员变量接受参数,所以无法使用单例模式,只能使用多例。

3.经过专业人员的大量测试,Struts2 的处理速度要比 SpringMVC 慢,原因是 Struts2 使用了 Struts 标签,Struts 标签由于设计原因,会出现加载数据慢的情况

这里仅仅比较了 Spring MVC 在某些方面相比 Struts2 的优势,但这并不能说明
Spring MVC 比 Struts2 优秀,仅仅因为早期 Struts2 使用广泛,所以出现的漏洞也比较多,但是在新版本的 Struts2 中也修复了许多漏洞。Spring MVC 自诞生以来,几乎没有什么致命的漏洞 。且 Spring MVC 基于方法开发,这一点较接近 Service 开发,这也是 Spring MVC 近年来备受关注的原因之一。

Spring MVC 执行流程⚠️

在这里插入图片描述

SpringMVC 的执行流程如下。

  1. 用户点击某个请求路径,发起一个 HTTP request 请求,该请求会被提交到 DispatcherServlet(前端控制器);
  2. 由 DispatcherServlet 请求一个或多个 HandlerMapping(处理器映射器),并返回一个执行链(HandlerExecutionChain)。
  3. DispatcherServlet 将执行链返回的 Handler 信息发送给 HandlerAdapter(处理器适配器);
  4. HandlerAdapter 根据 Handler 信息找到并执行相应的 Handler(常称为 Controller);
  5. Handler 执行完毕后会返回给 HandlerAdapter 一个 ModelAndView 对象(Spring MVC的底层对象,包括 Model 数据模型和 View 视图信息);
  6. HandlerAdapter 接收到 ModelAndView 对象后,将其返回给 DispatcherServlet ;
  7. DispatcherServlet 接收到 ModelAndView 对象后,会请求 ViewResolver(视图解析器)对视图进行解析;
  8. ViewResolver 根据 View 信息匹配到相应的视图结果,并返回给 DispatcherServlet;
  9. DispatcherServlet 接收到具体的 View 视图后,进行视图渲染,将 Model 中的模型数据填充到 View 视图中的 request 域,生成最终的 View(视图);
  10. 视图负责将结果显示到浏览器(客户端)。

Spring MVC接口

Spring MVC 涉及到的组件有 DispatcherServlet(前端控制器)、HandlerMapping(处理器映射器)、HandlerAdapter(处理器适配器)、Handler(处理器)、ViewResolver(视图解析器)和 View(视图)。下面对各个组件的功能说明如下。
1)DispatcherServlet
DispatcherServlet 是前端控制器,从图 1 可以看出,Spring MVC 的所有请求都要经过 DispatcherServlet 来统一分发。DispatcherServlet 相当于一个转发器或中央处理器,控制整个流程的执行,对各个组件进行统一调度,以降低组件之间的耦合性,有利于组件之间的拓展。
2)HandlerMapping
HandlerMapping 是处理器映射器,其作用是根据请求的 URL 路径,通过注解或者 XML 配置,寻找匹配的处理器(Handler)信息。
3)HandlerAdapter
HandlerAdapter 是处理器适配器,其作用是根据映射器找到的处理器(Handler)信息,按照特定规则执行相关的处理器(Handler)。
4)Handler
Handler 是处理器,和 Java Servlet 扮演的角色一致。其作用是执行相关的请求处理逻辑,并返回相应的数据和视图信息,将其封装至 ModelAndView 对象中。
5)View Resolver
View Resolver 是视图解析器,其作用是进行解析操作,通过 ModelAndView 对象中的 View 信息将逻辑视图名解析成真正的视图 View(如通过一个 JSP 路径返回一个真正的 JSP 页面)。
6)View
View 是视图,其本身是一个接口,实现类支持不同的 View 类型(JSP、FreeMarker、Excel 等)。

以上组件中,需要开发人员进行开发的是处理器(Handler,常称Controller)和视图(View)。通俗的说,要开发处理该请求的具体代码逻辑,以及最终展示给用户的界面。

注意⚠️:由于 Spring MVC 结构比较复杂,所以学习的时候也要掌握学习方法。首先要明确 Spring MVC 是一个工具,既然是工具,那么我们就需要先掌握工具的使用方法,不要陷入细节中,深入浅出,慢慢通过实际运用来加深对其的理解。

SpringMVC 的入门

创建项目

在这里插入图片描述
添加archetypeCatalog信息处理创建项目过慢的问题
在这里插入图片描述
在这里插入图片描述

Maven项目在pom.xml 文件总添加以下内容:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>springmvc-study</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>springmvc-study Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <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>
    <spring.version>5.0.2.RELEASE</spring.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.2</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>

  <build>
    <finalName>springmvc-study</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>


  1. web.xml配置
    Spring MVC 是基于 Servlet 的,DispatcherServlet 是整个 Spring MVC 框架的核心,主要负责截获请求并将其分派给相应的处理器处理。所以配置 Spring MVC,首先要定义 DispatcherServlet。跟所有 Servlet 一样,用户必须在 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 version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
	http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

    <display-name>Archetype Created Web Application</display-name>

    <!--配置解决中文乱码的过滤器-->
    <filter>
        <filter-name>characterEncodingFilter</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>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- 部署 DispatcherServlet -->
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 表示容器再启动时立即加载servlet -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <!-- 处理所有URL -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>


</web-app>

2)创建Spring MVC配置文件
在 WEB-INF 目录下创建 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"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- LoginController控制器类,映射到"/login" -->
    <bean name="/login"
          class="net.biancheng.controller.LoginController"/>
    <!-- LoginController控制器类,映射到"/register" -->
    <bean name="/register"
          class="net.biancheng.controller.RegisterController"/>

</beans>

  1. 创建Controller
    在 src 目录下创建 net.biancheng.controller 包,并在该包中创建 RegisterController 和 LoginController 两个传统风格的控制器类(实现 Controller 接口),分别处理首页中“注册”和“登录”超链接的请求。
public class LoginController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
       return new ModelAndView("/WEB-INF/jsp/register.jsp");
    }
}

public class RegisterController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        return new ModelAndView("/WEB-INF/jsp/register.jsp");
    }
}
  1. 创建View
    index.jsp 代码如下
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    未注册的用户,请
    <a href="${pageContext.request.contextPath }/register"> 注册</a><br /> 已注册的用户,去
    <a href="${pageContext.request.contextPath }/login"> 登录</a></body>
</html>

在 WEB-INF 下创建 jsp 文件夹,将 login.jsp 和 register.jsp 放到 jsp 文件夹下。login.jsp 代码如下。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    登录页面!
</body>
</html>

register.jsp 代码如下。

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
<body>
    注册页面!
</body>
</html>
</head>
  1. 部署运行

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

启动服务器,加载哪些配置文件

  1. web.xml 文件 部署描述服务文件,给服务器(tomcat)使用的
    作用: 服务器在启动的时候,读取web.xml,根据文件中的声明创建各种对象
  2. 框架的配置文件,springmvc的配置文件
    作用:声明框架创建的项目中的各种对象,主要是创建controller对象的

配置文件的家在顺序和功能

  1. tomcat服务器启动,读取web.xml,根据web.xml文件中的说明,创建对象
<!-- 声明Springmvc核心组件 -->
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 表示容器再启动时立即加载servlet -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
<!--
    表示服务器tomcat创建对象的顺序,是一个整数值,大于等于0
    值越小,创建对象的时间越早
    -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <!-- 处理所有URL -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

创建DispatcherServlet的对象,会执行init()方法。在init()方法中会执行springmvc容器对象创建WebApplicationContext ctx=new ClassPathXmlApplicationContext(“classpath:springmvc.xml”);

  1. springmvc框架,new ClassPathXmlApplicationContext() 读取springmvc配置文件
<!--  开启注解扫描  -->
    <context:component-scan base-package="com.study"/>

    <!-- 开启SpringMVC框架注解的支持-->
    <mvc:annotation-driven conversion-service="conversionService"/>
<!--    <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>
    <!--    配置自定义类型转换器-->
    <bean id="conversionServiceFactoryBean" class="org.springframework.context.support.ConversionServiceFactoryBean">
       <!--给工厂输入新的类型转换器-->
        <property name="converters">
            <set>
                <!--配置自定义类型转换器-->
                <bean class="com.study.util.SpringToDateConverter"/>
            </set>
        </property>
    </bean>

使用组件扫描器base-package=“com.study” ,遍历路径下的所有类。
找到类中的@Controller 、@RequestMapping注解,就能创建Controller对象,知道/doSome 请求是执行doSome()方法
以上1、2 都是项目启动的过程,没有执行任何的用户请求

SpringMVC框架基于组件方式执行流程

在这里插入图片描述
在这里插入图片描述

pom.xml文件标签

请求参数的绑定

绑定机制

在这里插入图片描述

请求参数绑定String 上

##html
<a href="testString?username=张三" >testString	</a>

## java 
@RequestMapping("testString")
public String testString(String username){
	System.out.println("username = "+username)
	return null;
}

## 方法的形参名称需要和请求参数名保持一致
## 当方法名称和请求参数名称不一致时可以使用@RequestParam("请求参数的名称")注解,
需要注意⚠️的是 使用RequestParam后的参数是必填的
## 使用方式
@RequestMapping("testString")
public String testString(@RequestParam("请求参数的名称")String username){...}

请求参数绑定JavaBean上


## 实体类
public class Account {
    private String userName;
    private String password;
    private Double money;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Double getMoney() {
        return money;
    }

    public void setMoney(Double money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "Account{" +
                "userName='" + userName + '\'' +
                ", password='" + password + '\'' +
                ", money=" + money +
                '}';
    }
}

##controller
@Controller
public class AccountController {
    @RequestMapping("saveAccount")
    public String saveAccount(Account account){
        System.out.println(account.toString());
        return "success";
    }
}

##请求接口
http://localhost:8080/springmvc_study_war/saveAccount?userName=张三&password=123123&money=1

在这里插入图片描述

请求参数绑定集合类型

## Account 实体类追加 list ,map 属性
private List<Account> list;
private Map<String,Account> map;
public List<Account> getList() {
        return list;
    }

    public void setList(List<Account> list) {
        this.list = list;
    }

    public Map<String, Account> getMap() {
        return map;
    }

    public void setMap(Map<String, Account> map) {
        this.map = map;
    }
    @Override
    public String toString() {
        return "Account{" +
                "userName='" + userName + '\'' +
                ", password='" + password + '\'' +
                ", money=" + money +
                ", list=" + list +
                ", map=" + map +
                '}';
    }
    
    ## html
    <form action="saveAccount" method="post">
    	姓名:<input type="text" name="userName"/><br/>
    	密码:<input type="text" name="password"/><br/>
    	金额:<input type="text" name="money"/><br/>

		用户姓名:<input type="text" name="list[0].userName"/><br/>
		用户密码:<input type="text" name="list[0].password"/><br/>

		用户姓名:<input type="text" name="map['one'].userName"/><br/>
		用户密码:<input type="text" name="map['one'].password"/><br/>
		<input type="submit" value="提交"/><br/>
	</form>

在这里插入图片描述
在这里插入图片描述

自定义类型转换器

以时间格式为例,系统默认的时间格式为yyyy-mm-dd 的格式,如果用户输入的时间格式为yyyy/mm/dd 格式的时间,系统则会报错,这个时候就可以用自定义类型转换器来实现

第一步:定义一个类,实现Converter接口,该接口有两个泛型。

## 接口
@FunctionalInterface
public interface Converter<S, T> {
    @Nullable
    T convert(S var1);
}


## converter 接口实现类
public class SpringToDateConverter implements Converter<String, Date> {

    /**
     *
     * @param s 时间格式的字符串
     * @return
     */
    @Override
    public Date convert(String s) {
        //判断
        if (s == null){
            throw  new RuntimeException("请您输入数据");
        }
        DateFormat df =new SimpleDateFormat("yyyy-mm-dd");
        try {
            //把字符串转换日期
            return df.parse(s);
        } catch (Exception e) {
            throw  new RuntimeException("数据类型转换错误");
        }
    }
}

##springmvc.xml
 <!--    配置自定义类型转换器-->
    <bean id="conversionServiceFactoryBean" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="com.study.util.SpringToDateConverter"/>
            </set>
        </property>
    </bean>
    
  <mvc:annotation-driven conversion-service="conversionService"/>

在这里插入图片描述
在这里插入图片描述

获取Servlet原生API

在这里插入图片描述

常用注解

Controller 注解

在SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model ,然后再把该Model 返回给对应的View 进行展示。在SpringMVC 中提供了一个非常简便的定义Controller 的方法,你无需继承特定的类或实现特定的接口,只需使用@Controller 标记一个类是Controller ,然后使用@RequestMapping 和@RequestParam 等一些注解用以定义URL 请求和Controller 方法之间的映射,这样的Controller 就能被外界访问到。此外Controller 不会直接依赖于HttpServletRequest 和HttpServletResponse 等HttpServlet 对象,它们可以通过Controller 的方法参数灵活的获取到。

@Controller 用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller 对象。分发处理器将会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping 注解。@Controller 只是定义了一个控制器类,而使用@RequestMapping 注解的方法才是真正处理请求的处理器。单单使用@Controller 标记在一个类上还不能真正意义上的说它就是SpringMVC 的一个控制器类,因为这个时候Spring 还不认识它。那么要如何做Spring 才能认识它呢?这个时候就需要我们把这个控制器类交给Spring 来管理。有两种方式:

RequestMapping注解

RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。

RequestMapping注解有六个属性,下面我们把她分成三类进行说明(下面有相应示例)。

参数名称说明
value指定请求的实际地址,指定的地址可以是URI Template 模式(后面将会说明)
method指定请求的method类型, GET、POST、PUT、DELETE等;
consumes指定处理请求的提交内容类型(Content-Type),例如application/json,text/html;
produces指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;
params指定request中必须包含某些参数值是,才让该方法处理。
headers指定request中必须包含某些指定的header值,才能让该方法处理请求。

注解的作用

作用: 用于建立请求URL和处理请求方法之间的对应关系

客户端一定会发一个请求过来,那么后台一定要有一个方法去执行它。
把发送请求的这个地址路径跟这个方法建立一个映射关联
你发送这个请求,那我这个方法就执行。
那么RequestMapping 就是来建立两者之间的关系的
反过来理解一下:我们写了一个方法,那别人想请求这个方法怎么办?
我们需要加一个映射关联,再这个方法上加一个RequestMapping注解。
我们只要请求RequsetMapping(path=“xxx”)
path中的xxx地址,就可以执行这个方法了。

RequestMapping可以作用在方法和类上
在这里插入图片描述
在这里插入图片描述

注解的属性

属性:

value:用于指定请求的 URL。它和 path 属性的作用是一样的。
method:用于指定请求的方式。
params:用于指定限制请求参数的条件。它支持简单的表达式。要求请求参数的 key 和 value 必须和 配置的一模一样。
例如:

params = {“accountName”},表示请求参数必须有 accountName
params = {“moeny!100”},表示请求参数中 money 不能是 100。
headers:用于指定限制请求消息头的条件。

/**
* 删除账户
* 参数中: accountName必须存在,
* 且money要大于100 ,接口方式为post,请求头中需要包含Accept参数
* @return
*/
@RequestMapping(value="/removeAccount",
params= {"accountName","money>100"},
method={RequestMethod.POST},heads={"Accept"})
public String removeAccount() {
	System.out.println("删除了账户");
	return "success";
}

注意:

以上四个属性只要出现 2 个或以上时,他们的关系是与的关系。

作用:

用于建立请求URL和处理请求方法之间的对应关系。

出现位置:

请求 URL 的第一级访问目录。此处不写的话,就相当于应用的根目录。写的话需要以/开头。

@Resource和@Autowired注解

@Resource和@Autowired都是做bean的注入时使用,其实@Resource并不是Spring的注解,它的包是javax.annotation.Resource,需要导入,但是Spring支持该注解的注入。

1、共同点

两者都可以写在字段和setter方法上。两者如果都写在字段上,那么就不需要再写setter方法。

2、不同点

(1)@Autowired

@Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired;只按照byType注入。

@Component注解

相当于通用的注解,当不知道一些类归到哪个层时使用,但是不建议。

@Repository注解

用于注解dao层,在daoImpl类上面注解。

RequestParam注解

@requestParam主要用于在SpringMVC后台控制层获取参数,类似一种是request.getParameter(“name”),它有三个常用参数:defaultValue = “0”, required = false, value = “isApp”;defaultValue 表示设置默认值,required 通过boolean设置是否是必须要传入的参数,value 值表示接受的传入的参数类型。
在这里插入图片描述
在这里插入图片描述

RequestBody注解

作用: 该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。

使用时机:返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用;
在这里插入图片描述
在这里插入图片描述

PathVaribale注解

用于将请求URL中的模板变量映射到功能处理方法的参数上,即取出uri模板中的变量作为参数。如:

@Controller  
public class TestController {  
     @RequestMapping(value="/user/{username}",method = RequestMethod.GET)  
     public String getLogin(@PathVariable("username") String userName){  
         System.out.println("userName:" + userName);  
        
         return "success";  
     }  
}

在这里插入图片描述

REST风格URL!

在这里插入图片描述

在这里插入图片描述

HiddentHttpMethodFilter的示例!

在这里插入图片描述

RequestHeader注解!

在这里插入图片描述

在这里插入图片描述

CookieValue注解!

在这里插入图片描述
在这里插入图片描述

ModelAttribute注解!

在这里插入图片描述
在这里插入图片描述

基于Map的应用场景示例:ModelAttrbute修饰方法带返回值!

在这里插入图片描述

基于Map的应用场景示例:ModelAttrbute修饰方法不带返回值!

在这里插入图片描述

SessionAttribute注解!

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

删除session中的信息!

在这里插入图片描述

响应之返回值为String类型!

在这里插入图片描述
在这里插入图片描述

响应之返回值为void类型

在这里插入图片描述
在这里插入图片描述

转发请求

forward后面传递的是页面或者服务器端其他url地址,不经过视图解析器,所以返回的地址需要加上WEB-INF和.jsp

没有返回值,系统会默认根据RequestMapping找页面,如果不想返回页面,但又想用void,可以用request转发请求

在这里插入图片描述
不会经过页面解析器,所以路径需要自己填写全,

重定向

因为重定向是两次请求,两次响应,在服务器给定重定向后,实际上只是给了浏览器端一个下一次请求的地址,这时浏览器重新请求,如果jsp在WEB-INF下则会报404错误,因为对于WEB-INF下的jsp文件只能通过请求转发进行,而对于web下的jsp文件能正常进行访问

    //方式1    
    @RequestMapping("/testVoid")
    public void testVoid(HttpServletRequest request, HttpServletResponse response) throws IOException {
    
    response.sendRedirect("/WEB-INF/pages/xxx.jsp");
    }

    //方式2 
     @RequestMapping("/testVoid")
    public void testVoid(HttpServletRequest request, HttpServletResponse response) throws IOException {
      
    return "redirect:/WEB-INF/pages/xxx.jsp";
    }

在这里插入图片描述

直接进行响应内容

通过HttpServletResponse对象直接将内容响应给浏览器

@RequestMapping("/testVoid")
public void testVoid(HttpServletRequest request,HttpServletResponse response) throws Exception{
	//设置编码
	response.setCharacterEncoding("UTF-8");
	response.setContextType("text/html;charset=UTF-8");
	//直接进行响应
	response.getWriter().print("您好");
}

在这里插入图片描述

响应之返回值为ModelAndView对象

    /**
     * 当框架调用完doSome()方法后,得到返回ModelAndView。
     * 框架会在后续的处理逻辑值,处理mv对象里面的数据和视图。
     * 对于数据执行request.setAttribute("msg","处理了some.do 请求");把数据放入到request作用域中
     * 对于视图执行forward转发操作,等同于request.getRequestDispather("success").forward(..)
     * @return
     */
    public ModelAndView doSome(){
        ModelAndView modelAndView=new ModelAndView();
        System.out.println("执行了doSome方法");
        modelAndView.addObject("msg","处理了some.do 请求");
        modelAndView.setViewName("success");
        return modelAndView;
    }
## 请求页面
<a href="doSome"> doSome</a>

## 响应页面内容success.jsp
内容是:${msg}


## 响应结果:
内容是: 处理了some.do 请求

注意⚠️:会经过视图解析器的,

响应之使用forward和redirect进行页面跳转

在这里插入图片描述
在这里插入图片描述

响应json数据之过滤静态资源!

在这里插入图片描述

在这里插入图片描述

响应json数据之发送ajax请求

$.ajax() 参数很多,其中最常见的有:

参数名称参数类型参数说明
urlString默认值当前页地址,发送请求的地址
typeString默认值为get,表示请求方式,除了post之外,还支持put和delete 依赖于浏览器
contentTypestring默认值为 application/x-www-form-urlencode。这个属性表示发送给服务器的内容的编码类型。默认值适用大多数情况。
dataString 或者对象发送到浏览器的请求参数。本质上$.ajax()需要的是字符串,如果你传入的是Object,jQuery会将它自动转换成Query String格式
dataTypeString预测浏览器返回的数据类型。如果不指定,jQuery会更具HTTP中的MIME信息进行推测。常用有:xml、html、json、Text
successfunction请求成功 (响应状态吗为200) 后调用此函数。参数是有服务器返回的数据(具体数据和dataType无关);描述状态的字符串
asyncboolean默认为true,表示异步请求。设置为false则表示使用同步方式发起请求。

在这里插入图片描述
除此之外,$.ajax() 方法,还可以设定 beforeSend(提交前回调)、error(请求失败后回调)、success(请求成功返回后回调)以及 complete(请求完成回调,无论成功失败后 )回调函数。

参数名称参数类型参数说明
beforeSend(XHR)function发送前回调函数。可以修改 xmlHttpRequest 对象。如果返回false,则可以取消本次请求。XMLHttpRequest 对象是该方法唯一参数
contextobject用于设置 AJAX 回调函数的上下文。也就是说,让回调函数内的 this 指向这个对象。如果没有设置它,那么回调函数中的 this 指向的是本次 AJAX 请求时传递的 options 参数。
errorfunction失败时调用此函数 有三个参数:XMLHttpRequest对象、错误信息、可选的异常对象
complete(XHR, TS)function请求完成后调用此函数(成功或失败都调用)。参数::XMLHttpRequest对象 和 一个描述请求类型的字符串
timeoutnumber设置请求超时时间(毫秒)

响应json数据之响应json格式数据

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

文件上传之传统方式上传!

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

文件上传之SpringMVC方式上传

SpringMVC上传原理:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

文件上传之SpringMVC跨服务器上传

在这里插入图片描述
后台代码沿用fileupload2方法
在这里插入图片描述

在这里插入图片描述

SpringMVC异常处理

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

SpringMVC拦截器!

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

HttpMessageConverter消息转化器

HttpMessageConverter接口作用
1) 实现请求的数据转换为json对象
2) 将控制器方法返回的对象转为json,xml,text,二进制等不同格式的数据

MediaType :媒体类型,表示互联网中数据的格式,例如application/json,text/html,image/gif

public interface HttpMessageConverter<T>{
	
	/**
	*作用: 检查clazz这个类型的对象,能否转为mediaType对象表示的数据格式
	*如果能转为mediaType表示的类型,返回true,返回true调用read()
	*/
 	boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);
	/**
	*	作用:接受请求中的数据,把数据转为Clazz表示的对象
	*/
    T read(Class<? extends T> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException;
	/**
	*作用: 检查clazz这种数据类型,能否转为mediaType表示的数据格式
	*/
    boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);
	/**
	* 作用:把t对象,按照contentType说明的格式,把对象转为json或者xml
	*/
    void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException;

}
实现类:
	MappingJackson2HttpMessageConverter:使用jackson工具库中的objectMapper把java对象转为json数据格式
	StringHttpMessageConverter: 把字符串类型的返回数据,进行格式转换和编码

常见问题

post请求中携带中文,中文乱码

在web.xml中添加
1.方式一:
对于接收的请求参数,如果含有中文,则会出现中文乱码问题。
Spring对于请求参数中的中文乱码问题,给出了专门的字符集过滤器:
spring-web-5.2.5.RELEASE.jar 的org.springframework.web.filter包下的CharacterEncodingFilter

 <!--配置解决中文乱码的过滤器-->
    <filter>
        <filter-name>characterEncodingFilter</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>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

2.方式二:在接收参数之前设置编码格式(不建议使用)

request.setCharacterEncoding(“UTF-8”);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值