SpringMVC 学习笔记

MVC设计模型

  • M : model 模型 —–>JavaBean

  • V : View 视图 ——> JSP

  • C : Controller控制器 —–> Servlet

MVC职责分析

  • Controller

    1. 取得表单数据
    2. 调用业务逻辑
    3. 转向指定的页面
  • Model

    1. 业务逻辑
    2. 保存数据的状态
  • View

    1. 显示页面

SpringMVC概述

​ SpringMVC是一种基于Java的实现MVC设计模型的请求驱动类型的轻量级Web框架,属于 Spring FrameWork 的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。

​ SpringMVC已经成为目前最主流的 MVC 框架之一,并且随着Spring3.0的发布,全面超越 Struts2,成为最优秀的 MVC 框架。 它通过一套注解,让一个简单的Java类成为处理请求的控制器,而无须实现任何接口。同时它还支持RESTful编程风格的请求。

SpringMVC在三层架构的位置

image-20210301144834860

SpringMVC详细的执行流程

image-20210302203740236

前端控制器的配置(配置在web.xml中)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!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>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>

其余配置在xml中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启注解扫描 -->
<context:component-scan base-package="com.wht"></context:component-scan>
<!-- 开启视图解析器 -->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 文件位置 -->
<property name="prefix" value="/WEB-INF/pages/"></property>
<!-- 文件后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 开启SpringMVC框架的注解支持并创建处理器映射器和处理器适配器 -->
<mvc:annotation-driven/>
</beans>

SpringMVC 相关注解的讲解

  • @RequestMapping():

    • 作用:与前端请求建立映射关联
    • 作用位置:
      • 方法上
      • 类上
    • 属性:
      • path:用于指定请求的URL
      • value:就等同于path
      • method:用于指定请求方式(get/post等)
      • params:用于指定限制请求参数的条件
        • 例如:
          • params = {“username”}表示必须有username属性
          • params = {“username !root”}表示必须有username属性并值不为root
      • headers:用于指定发送的请求中必须包含的请求头
  • @RequestParam():

    • 作用:把请求中的指定名称的参数传递给控制器中的形参赋值

    • 作用位置:

      • 方法参数
    • 属性:

      • value:就等同于path
      • required:请求参数中是否必须提供此参数,默认值是true,必须提供
  • @RequestBody():

    • 作用:用于获取请求体的内容(注意:get方法不可以)

    • 作用位置:

      • 方法参数
    • 属性:

      • required:是否必须有请求体,默认值是true
  • @PathVariable():

    • 作用:拥有绑定url中的占位符的。例如:url中有/delete/{id},{id}就是占位符

    • 作用位置:

      • 方法参数
    • 属性:

      • value:指定url中的占位符名称
  • @RequestHeader():

    • 作用:获取指定请求头的值

    • 作用位置:

      • 方法参数
    • 属性:

      • value:请求头的名称
  • @CookieValue():

    • 作用:用于获取指定cookie的名称的值

    • 作用位置:

      • 方法参数
    • 属性:

      • value:cookie的名称
  • @ModelAttribute():

    • 作用:1.出现在方法上:表示当前方法会在控制器方法执行前线执行。

      ​ 2. 出现在参数上:获取指定的数据给参数赋值。

    • 作用位置:

      • 方法
      • 方法参数
    • 使用场景:

      • 当提交表单数据不是完整的实体数据时,保证没有提交的字段使用数据库原来的数据。
    • 示例:

      • ```java
        /**
        • 作用在方法,先执行
        • @param name
        • @return
        • /
          @ModelAttribute
          public User showUser(String name) {
             System.out.println("showUser执行了...");
          
          // 模拟从数据库中查询对象
          User user = new User();
          user.setName(“哈哈”);
          user.setPassword(“123”);
          user.setMoney(100d);
          return user;
          }
          /**
        • 修改用户的方法
        • @param cookieValue
        • @return
        • /
          @RequestMapping(path=”/updateUser”)
          public String updateUser(User user) {
           System.out.println(user);
           return "success";
          
          }
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27

          - ```java
          /**
          * 作用在方法,先执行
          * @param name
          * @return
          */
          @ModelAttribute
          public void showUser(String name,Map<String, User> map) {
          System.out.println("showUser执行了...");
          // 模拟从数据库中查询对象
          User user = new User();
          user.setName("哈哈");
          user.setPassword("123");
          user.setMoney(100d);
          map.put("abc", user);
          }
          /**
          * 修改用户的方法
          * @param cookieValue
          * @return
          */
          @RequestMapping(path="/updateUser")
          public String updateUser(@ModelAttribute(value="abc") User user) {
          System.out.println(user);
          return "success";
          }
  • @SessionAttributes():

    • 作用:用于多次执行控制器方法间的参数共享

    • 作用位置:

      • 类上
    • 属性:

      • value:指定存入属性的名称
    • 示例:

      • ```java
        @Controller
        @RequestMapping(path=”/user”)
        @SessionAttributes(value= {“username”,”password”,”age”},types=
        {String.class,Integer.class}) // 把数据存入到session域对象中
        public class HelloController {
        /**
        • 向session中存入值
        • @return
        • /
          @RequestMapping(path=”/save”)
          public String save(Model model) {
           System.out.println("向session域中保存数据");
           model.addAttribute("username", "root");
           model.addAttribute("password", "123");
           model.addAttribute("age", 20);
           return "success";
          
          }
          /**
        • 从session中获取值
        • @return
        • /
          @RequestMapping(path=”/find”)
          public String find(ModelMap modelMap) {
           String username = (String) modelMap.get("username");
           String password = (String) modelMap.get("password");
           Integer age = (Integer) modelMap.get("age");
           System.out.println(username + " : "+password +" : "+age);
           return "success";
          
          }
          /**
        • 清除值
        • @return
        • /
          @RequestMapping(path=”/delete”)
          public String delete(SessionStatus status) {
           status.setComplete();
           return "success";
          
          }
          }
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          49
          50
          51
          52
          53
          54
          55
          56
          57
          58
          59
          60
          61
          62

          -

          ## SpringMVC请求参数的绑定

          1. 请求参数的绑定说明

          1. 绑定机制

          1. 表单提交的数据都是k=v格式的 username=haha&password=123
          2. SpringMVC的参数绑定过程是把表单提交的请求参数,作为控制器中方法的参数进行绑定的
          3. 要求:提交表单的name和参数的名称是相同的

          2. 支持的数据类型

          1. 基本数据类型和字符串类型
          2. 实体类型(JavaBean)
          3. 集合数据类型(List、map集合等)

          注意事项:

          1. 基本数据类型和字符串类型

          1. 提交表单的name和参数的名称是相同的

          2. 区分大小写

          2. 实体类型(JavaBean)

          1. 提交表单的name和JavaBean中的属性名称需要一致
          2. 如果一个JavaBean类中包含其他的引用类型,那么表单的name属性需要编写成:对象.属性 例如:address.name

          ​ 3.给集合属性数据封装

          ​ 1.JSP页面编写方式:list[0].属性 ,map['key'].属性

          ## SpringMVC中文乱码的解决

          1. 处理post请求乱码

          在web.xml中配置Spring提供的过滤器类

          ```xml
          <!-- 配置过滤器,解决中文乱码的问题 -->
          <filter>
          <filter-name>characterEncodingFilter</filter-name>
          <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filterclass>
          <!-- 指定字符集 -->
          <init-param>
          <param-name>encoding</param-name>
          <param-value>UTF-8</param-value>
          </init-param>
          <!-- 顺手处理响应乱码 -->
          <init-param>
          <param-name>forceEncoding</param-name>
          <param-value>true</param-value>
          </init-param>
          </filter>
          <filter-mapping>
          <filter-name>characterEncodingFilter</filter-name>
          <url-pattern>/*</url-pattern>
          </filter-mapping>
  1. 处理get请求乱码

    在tomcat的server.xml中在8080端口处加 URIEncoding=”UTF-8”

  2. 处理响应乱码:

    添加response.setContentType(“text/html;charset=utf-8”);

SpringMVC自定义类型转换器

  1. 表单提交的任何数据类型全部都是字符串类型,但是后台定义Integer类型,数据也可以封装上,说明
    Spring框架内部会默认进行数据类型转换。
  2. 如果想自定义数据类型转换,可以实现Converter的接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class StringToDateConverter implements Converter<String, Date> {
@Override
public Date convert(String s) {
//判断
if(s==null){
throw new RuntimeException("请您传入数据");
}
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
try{
return df.parse(s);
} catch (ParseException e) {
throw new RuntimeException("数据类型转换出现错误");
}
}
}
  1. 注册自定义类型转换器,在springmvc.xml配置文件中编写配置
1
2
3
4
5
6
7
8
9
10
<!-- 注册自定义类型转换器 -->
<bean id="conversionService"class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="cn.itcast.utils.StringToDateConverter"/>
</set>
</property>
</bean>
<!-- 开启Spring对MVC注解的支持 -->
<mvc:annotation-driven conversion-service="conversionService"/>

控制器中使用原生的ServletAPI对象

只需要在控制器的方法参数定义HttpServletRequest和HttpServletResponse对象