【精选】SpringMVC简介及其执行流程,参数获取方式

SpringMVC简介

在这里插入图片描述

MVC模型

在这里插入图片描述

MVC全称Model View Controller,是一种设计创建Web应用程序的模式。这三个单词分别代表Web应用程序的三个部分:

  • Model(模型):指数据模型。用于存储数据以及处理用户请求的业务逻辑。在Web应用中,JavaBean对象,业务模型等都属于Model。

  • View(视图):用于展示模型中的数据的,一般为jsp或html文件。

  • Controller(控制器):是应用程序中处理用户交互的部分。接受视图提出的请求,将数据交给模型处理,并将处理后的结果交给视图显示。

SpringMVC

SpringMVC是一个基于MVC模式的轻量级Web框架,是Spring框架的一个模块,和Spring可以直接整合使用。SpringMVC代替了Servlet技术,它通过一套注解,让一个简单的Java类成为处理请求的控制器,而无须实现任何接口。

在这里插入图片描述

SpringMVC入门案例

接下来我们编写一个SpringMVC的入门案例

  1. 使用maven创建web项目,补齐包结构。

  2. 引入相关依赖和tomcat插件

    <dependencies>
      <!-- Spring核心模块 -->
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.12.RELEASE</version>
      </dependency>
      <!-- SpringWeb模块 -->
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>5.2.12.RELEASE</version>
      </dependency>
      <!-- SpringMVC模块 -->
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.12.RELEASE</version>
      </dependency>
      <!-- Servlet -->
      <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
      </dependency>
      <!-- JSP -->
      <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.0</version>
        <scope>provided</scope>
      </dependency>
    </dependencies>
    
    
    <build>
      <plugins>
        <!-- tomcat插件 -->
        <plugin>
          <groupId>org.apache.tomcat.maven</groupId>
          <artifactId>tomcat7-maven-plugin</artifactId>
          <version>2.1</version>
          <configuration>
            <port>8080</port>
            <path>/</path>
            <uriEncoding>UTF-8</uriEncoding>
            <server>tomcat7</server>
            <systemProperties>
              <java.util.logging.SimpleFormatter.format>%1$tH:%1$tM:%1$tS %2$s%n%4$s: %5$s%6$s%n
              </java.util.logging.SimpleFormatter.format>
            </systemProperties>
          </configuration>
        </plugin>
      </plugins>
    </build>
    
  3. 在web.xml中配置前端控制器DispatcherServlet。

    <web-app>
      <display-name>Archetype Created Web Application</display-name>
      <!--SpringMVC前端控制器,本质是一个Servlet,接收所有请求,在容器启动时就会加载-->
      <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>
    

编写SpringMVC核心配置文件springmvc.xml,该文件和Spring配置文件写法一样。

<?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.springMVC"/>


  <!-- 开启SpringMVC注解的支持 -->
  <mvc:annotation-driven/>


</beans>

编写控制器

@Controller
public class MyController1 {
  // 该方法的访问路径是/c1/hello1
  @RequestMapping("/c1/hello1")
  public void helloMVC(){
    System.out.println("hello SpringMVC!");
   }
}

使用tomcat插件启动项目,访问 http://localhost:8080/c1/hello1

SpringMVC执行流程

在这里插入图片描述

SpringMVC的组件

  • DispatcherServlet:前端控制器,接受所有请求,调用其他组件。
  • HandlerMapping:处理器映射器,根据配置找到方法的执行链。
  • HandlerAdapter:处理器适配器,根据方法类型找到对应的处理器。
  • ViewResolver:视图解析器,找到指定视图。

组件的工作流程

在这里插入图片描述

  1. 客户端将请求发送给前端控制器。
  2. 前端控制器将请求发送给处理器映射器,处理器映射器根据路径找到方法的执行链,返回给前端控制器。
  3. 前端控制器将方法的执行链发送给处理器适配器,处理器适配器根据方法类型找到对应的处理器。
  4. 处理器执行方法,将结果返回给前端控制器。
  5. 前端控制器将结果发送给视图解析器,视图解析器找到视图文件位置。
  6. 视图渲染数据并将结果显示到客户端。

SpringMVC参数获取

在这里插入图片描述

封装为简单数据类型

在Servlet中我们通过request.getParameter(name)获取请求参数。该方式存在两个问题:

  • 请求参数较多时会出现代码冗余。
  • 与容器紧耦合。

而SpringMVC支持参数注入的方式用于获取请求数据,即将请求参数直接封装到方法的参数当中。用法如下:

  1. 编写控制器方法

    // 获取简单类型参数
    @RequestMapping("/c1/param1")
    public void simpleParam(String username,int age){
      System.out.println(username);
      System.out.println(age);
    }
    
  2. 访问该方法时,请求参数名和方法参数名相同,即可完成自动封装。

    http://localhost:8080/c1/param1?username=bz&age=10

封装为对象类型

SpringMVC支持将参数直接封装为对象,写法如下:

封装单个对象
  1. 编写实体类

    public class Student {
      private int id;
      private String name;
      private String sex;
      // 省略getter/setter/tostring
    }
    
  2. 编写控制器方法

    // 获取对象类型参数
    @RequestMapping("/c1/param2")
    public void objParam(Student student){
      System.out.println(student);
    }
    
    
  3. 访问该方法时,请求参数名和方法参数的属性名相同,即可完成自动封装。

    http://localhost:8080/c1/param2?id=1&name=bz&sex=female

封装关联对象
  1. 编写实体类

    public class Address {
      private String info; //地址信息
      private String postcode; //邮编
      // 省略getter/setter/tostring
    }
    public class Student {
      private int id;
      private String name;
      private String sex;
      private Address address; // 地址对象
      // 省略getter/setter/tostring
    }
    
  2. 编写控制器方法

    // 获取关联对象类型参数
    @RequestMapping("/c1/param3")
    public void objParam2(Student student){  
      System.out.println(student);
    }
    
  3. 访问该方法时,请求参数名和方法参数的属性名相同,即可完成自动封装。

    http://localhost:8080/c1/param3?id=1&name=bz&sex=female&address.info=beijing&address.postcode=030000

    我们也可以使用表单发送带有参数的请求:

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
    <title>表单提交</title>
    </head>
    <body>
    <form action="/c1/param3" method="post">
      id:<input name="id">
      姓名:<input name="name">
      性别:<input name="sex">
      住址:<input name="address.info">
      邮编:<input name="address.postcode">
      <input type="submit">
    </form>
    </body>
    </html>
    

封装为集合类型

SpringMVC支持将参数封装为List或Map集合,写法如下:

封装为List集合

封装为简单数据类型集合

  1. 编写控制器方法

    // 绑定简单数据类型List参数,参数前必须添加@RequestParam注解
    @RequestMapping("/c1/param4")
    public void listParam(@RequestParam List<String> users){ 
      System.out.println(users);
    }
    

    该方式也可以绑定数组类型:

    @RequestMapping("/c1/param5")
    public void listParam2(@RequestParam String[] users){ 
    System.out.println(users[0]); 
    System.out.println(users[1]);
    }
    
  2. 请求的参数写法

    http://localhost:8080/c1/param4?users=bj&users=springMVC

封装为对象类型集合

SpringMVC不支持将参数封装为对象类型的List集合但可以封装到有List属性的对象中。

  1. 编写实体类

    public class Student {
      private int id;
      private String name;
      private String sex;
      private List<Address> address; // 地址集合
      // 省略getter/setter/tostring
    }
    
  2. 编写控制器方法

    // 对象中包含集合属性
    @RequestMapping("/c1/param6")
    public void listParam3(Student student){
      System.out.println(student);
    }
    
  3. 请求的参数写法

    [http://localhost:8080/c1/param6?id=1&name=bz&sex=female&address0].info=bj&address[0].postcode=100010&address[1].info=sh&address[1].postcode=100011

封装为Map集合

同样,SpringMVC要封装Map集合,需要封装到有Map属性的对象中。

  1. 编写实体类

    public class Student {
      private int id;
      private String name;
      private String sex;
      private Map<String,Address> address; // 地址集合
        // 省略getter/setter/tostring
    }
    
  2. 编写控制器方法

    // 对象中包含Map属性
    @RequestMapping("/c1/param7")
    public void mapParam(Student student){  
      System.out.println(student);
    }
    
  3. 请求的参数写法

    [http://localhost:8080/c1/param7?id=1&name=bz&sex=female&address’one’].info=bj&address[‘one’].postcode=100010&address[‘two’].info=sh&address[‘two’].postcode=100011

使用Servlet原生对象获取参数

SpringMVC也支持使用Servlet原生对象,在方法参数中定义HttpServletRequestHttpServletResponseHttpSession等类型的参数即可直接在方法中使用。

// 使用Servlet原生对象
@RequestMapping("/c1/param8")
public void servletParam(HttpServletRequest request, HttpServletResponse response, HttpSession session){ 
  // 原生对象获取参数                           
  System.out.println(request.getParameter("name")); 
    System.out.println(response.getCharacterEncoding());  
    System.out.println(session.getId());
}

访问该方法即可:http://localhost:8080/c1/param8?name=zhangshan

一般情况下,在SpringMVC中都有对Servlet原生对象的方法的替代,推荐使用SpringMVC的方式代替Servlet原生对象。

自定义参数类型转换器

前端传来的参数全部为字符串类型,SpringMVC使用自带的转换器将字符串参数转为需要的类型。如:

// 获取简单类型参数
@RequestMapping("/c1/param1")
public void simpleParam(String username,int age){ 
  System.out.println(username);  
  System.out.println(age);
}

请求路径:http://localhost:8080/c1/param1?username=bz&age=10

但在某些情况下,无法将字符串转为需要的类型,如:

@RequestMapping("/c1/param9")
public void dateParam(Date birthday){ 
  System.out.println(birthday);
}

由于日期数据有很多种格式,SpringMVC没办法把所有格式的字符串转换成日期类型。比如参数格式为birthday=2025-01-01时,SpringMVC就无法解析参数。此时需要自定义参数类型转换器。

  1. 定义类型转换器类,实现Converter接口

    // 类型转换器必须实现Converter接口,两个泛型代表转换前的类型,转换后的类型
    public class DateConverter implements Converter<String, Date> {
      /**
       * 转换方法
       * @param source 转换前的数据
       * @return 转换后的数据
       */
      @Override
      public Date convert(String source) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
          date = sdf.parse(source);
         } catch (ParseException e) {
          e.printStackTrace();
         }
        return date;
       }
    }
    
    
  2. 注册类型转换器对象

    <!-- 配置转换器工厂 -->
    <bean id="converterFactory" class="org.springframework.context.support.ConversionServiceFactoryBean">
      <!-- 转换器集合 -->
      <property name="converters">
        <set>
          <!-- 自定义转换器 -->
          <bean class="com.springMVC.converter.DateConverter"></bean>
        </set>
      </property>
    </bean
      
    <!-- 使用转换器工厂 -->
    <mvc:annotation-driven conversion-service="converterFactory"></mvc:annotation-driven>
    
  3. 此时再访问http://localhost:8080/c1/param9?birthday=2025-01-01时,SpringMVC即可将请求参数封装为Date类型的参数。

编码过滤器

在传递参数时,tomcat8以上能处理get请求的中文乱码,但不能处理post请求的中文乱码

  1. 编写jsp表单

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
      <head>
        <title>编码过滤器</title>
      </head>
      <body>
        <form action="/cn/code" method="post">
           姓名:<input name="username">
          <input type="submit">
        </form>
      </body>
    </html>
    
  2. 编写控制器方法

    @RequestMapping("/cn/code")
    public void code(String username){
      System.out.println(username);
    }
    

SpringMVC提供了处理中文乱码的过滤器,在web.xml中配置该过滤器即可解决中文乱码问题:

<!--SpringMVC中提供的字符编码过滤器,放在所有过滤器的最上方-->
<filter>
  <filter-name>encFilter</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>encFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/240661.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C#基础——语法学习

C#的基本语法 在介绍基本语法之前我们先来大概讲一下创建好的这些文件都是做什么的 .sln文件&#xff1a;将项目和解决方案项结合到一起 .vs文件夹&#xff1a;用来存储当前解决方案中关于用户的设置和自定义项&#xff0c;比如断点&#xff0c;主题等。&#xff08;一般都将其…

短信打开小程序

获取 URL Scheme | 微信开放文档 静态网站 H5 跳小程序 | 微信开放文档

阿里云SMC迁移RedHat/CentOS 5 内核升级

阿里云SMC迁移RedHat/CentOS 5 内核升级 1. 起因 服务器需要迁移上阿里云,有几台服务器用的是Redhat 5.x,在使用SMC进行迁移时出现以下报错. [2023-12-13 09:50:55] [Error] Check System Info Failed, codeS16_111, msgGet OS Info Failed: [error] grub is too old for C…

工作随记:long类型数据迁移问题小记

文章目录 概要整体解决方法方法一&#xff1a;用COPY的方法&#xff1a;方法二&#xff1a;PL/SQL(如上)方法三&#xff1a;直接就把LONG转换成CLOB类型方法四&#xff1a;exp/imp 技术过程 概要 工作随记&#xff1a;在做技术方案发现客户数据库的表存在与系统表空间&#xf…

OpenAI 承认 ChatGPT 最近确实变懒,承诺修复问题

文章目录 一. ChatGPT 指令遵循能力下降引发用户投诉1.1 用户抱怨回应速度慢、敷衍回答、拒绝回答和中断会话 二. OpenAI 官方确认 ChatGPT 存在问题&#xff0c;展开调查三. OpenAI 解释模型行为差异&#xff0c;回应用户质疑四. GPT-4 模型变更受人事动荡和延期影响 一. Chat…

基于Java SSM框架实现固定设备资产管理系统项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架实现固定设备资产管理系统演示 摘要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所认…

二、结合各种图形库实现各种demo(11-20)

demo地址https://bidding-m.gitee.io/maptalks-test-next/#/ 11、isects 12、right click menu 13、infoWindow 14、image marker 15、multi image marker 16、vector-marker-fill 17、line-gradient-arrow 18、rotated-marker-with-line 19、smoothness-line 20、polygon 欢迎…

orb-slam2学习总结

目录 视觉SLAM 1、地图初始化 2、ORB_SLAM地图初始化流程 3、ORB特征提取及匹配 1、对极几何 2、对极约束 &#xff08;epipolar constraint&#xff09; 3、基础矩阵F、本质矩阵E 5、单目尺度不确定性 6、单应矩阵&#xff08;Homography Matrix&#xff09; 6.1 什么是单应矩…

干不完的996,加不完的007,浅谈程序员的内卷化

目录 一. 什么是内卷化 二. 程序员的内卷化 2.1. 码农时代 2.2. 开源时代 2.3. 加班文化 三. 如何不被内卷化 3.1. Stay Hungry, Stay Foolish 3.2. 工程能力 3.2.1. 架构 3.2.2. 规范 3.2.3. 管理 3.2.4. 排错 3.3. 学会思考 四. 结尾 一. 什么是内卷化 最近开始…

【算法与数据结构】37、LeetCode解数独

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;本题也是一道困难题&#xff0c;难点在于如何构建数独棋盘&#xff0c;如何检查棋盘的合法性&#xff…

Halcon一维码识别

文章目录 参数连接halcon 自带案例1&#xff08;设置校验位识别条码&#xff09;Halcon 自带案例2&#xff08;设置对比度识别条码&#xff09;Halcon 自带案例3&#xff08;存在曲面变形&#xff09;Halcon 自带案例4&#xff08;设置条码扫描线&#xff09;Halcon 自带案例5&…

Linux---Ubuntu操作系统

1. Ubuntu操作系统的介绍 Ubuntu操作系统是属于Linux操作系统中的一种&#xff0c;它是免费、稳定又可以拥有绚丽界面的一个操作系统 2. Ubuntu图形界面的介绍 任务栏 窗口操作按钮 窗口菜单条 任务栏效果图: 窗口操作按钮效果图: 窗口菜单条效果图: 3. 与Windows目录结…

『C++成长记』拷贝构造函数

&#x1f525;博客主页&#xff1a;小王又困了 &#x1f4da;系列专栏&#xff1a;C &#x1f31f;人之为学&#xff0c;不日近则日退 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、拷贝构造函数 &#x1f4d2;1.1拷贝构造函数的概念 &#x1f4d2;1.2拷贝构造…

Java项目-瑞吉外卖Day6

导入用户地址功能&#xff0c;为用户添加地址&#xff1a; 添加AddressBook实体类&#xff0c;创建相关service&#xff0c;mapper&#xff0c;serviceImpl&#xff0c;controller类。 controller类直接使用的资料提供的代码。 实现菜品展示移动端开发&#xff1a; 看到前端发…

添加,更换和删除 vSphere License

目录 1. 删除 License2. 添加 License&#xff08;1&#xff09;输入许可证密钥&#xff08;2&#xff09;编辑许可证名称&#xff08;3&#xff09;确认许可证信息 3. 分配/更换 License&#xff08;1&#xff09;为 vCenter Server 分配 License&#xff08;2&#xff09;为 …

Android : 序列化 Parcelable 简单应用

1.Parcelable 介绍 Parcelable 是 Android 提供的一个序列化接口&#xff0c;用于将数据写入 Parcel&#xff0c;以及从 Parcel 中读取数据。一个类只要实现了这个接口&#xff0c;该类的对象就可以被序列化&#xff0c;主要用于 IPC&#xff08;进程间通信&#xff09;、Bind…

产品经理之如何编写竞品分析(医疗HIS系统管理详细案例模板)

目录 一.项目周期 二.竞品分析的目的 三.竞品分析包含的维度 四.如何选择竞品 五.竞品画布 六.案例模板 一.项目周期 在整个项目的周期&#xff0c;产品经理所做的事情主要在项目前期做市场分析、需求调研等&#xff0c;下面一张图概况了整个项目周期产品经理、开发工程师…

网络安全——Iptables防DDoS攻击实验

一、实验目的要求&#xff1a; 二、实验设备与环境&#xff1a; 三、实验原理&#xff1a; 四、实验步骤&#xff1a; 五、实验现象、结果记录及整理&#xff1a; 六、分析讨论与思考题解答&#xff1a; 一、实验目的要求&#xff1a; 1、掌握常见DDoS攻击SYN Flood的攻击…

gdb本地调试版本移植至ARM-Linux系统

移植ncurses库 本文使用的ncurses版本为ncurses-5.9.tar.gz 下载地址&#xff1a;https://ftp.gnu.org/gnu/ncurses/ncurses-5.9.tar.gz 1. 将ncurses压缩包拷贝至Linux主机或使用wget命令下载并解压 tar-zxvf ncurses-5.9.tar.gz 2. 解压后进入到ncurses-5.9目录…

解决员工安全隐患的终极方案!迅软DSE答疑员工终端安全管控策略揭秘!

企业终端安全管控对于企事业单位来说至关重要。迅软DSE终端安全系统提供了丰富的终端安全桌面管理策略&#xff0c;可以对终端用户的上网行为和终端操作行为进行管理和控制&#xff0c;从而实现桌面终端的标准化管理&#xff0c;解决终端安全管理问题&#xff0c;并提高员工工作…