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

news2024/11/24 4:00:03

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>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

37.分支结构嵌套

目录 一.什么是分支结构嵌套 二.什么情况下会用分支结构嵌套 三.举例 四.注意事项 五.视频教程 一.什么是分支结构嵌套 在一个if语句中又包含了另外一个if语句&#xff0c;这种情况称之为if语句的嵌套&#xff0c;也叫做分支结构嵌套。 二.什么情况下会用分支结构嵌套 如…

dToF直方图之美_激光雷达多目标检测

直方图提供了一种简单有效的方法来分析信号分布并识别与目标存在相对应的峰值,并且能够可视化大量数据,让测距数形结合。在车载激光雷达中,对于多目标检测,多峰算法统计等,有着区别于摄像头以及其他雷达方案的天然优势。 如下图,当中有着清晰可见的三个峰值,我们可以非…

炸弹人游戏

代码实现 广度优先搜素 深度优先搜索

巧用RTL原语实现MUX门级映射

对于前端设计人员&#xff0c;经常会需要一个MUX来对工作模式&#xff0c;数据路径进行明确&#xff08;explicit&#xff09;的声明&#xff0c;这个对于中后端工程师下约束也很重要。这里介绍一种巧用的RTL原语&#xff0c;实现MUX的方法。闲言少叙&#xff0c;ICerGo&#x…

2023自动化测试框架大对比:哪个更胜一筹?

所谓工欲善其事&#xff0c;必先利其器&#xff0c;在进行自动化测试时&#xff0c;选择一个合适的框架是至关重要的。因为一个好的测试框架可以大大提高测试效率&#xff0c;减少我们很多工作量。在选择框架之前&#xff0c;我们通常需要对不同的框架进行对比&#xff0c;以便…

Python特征工程神器:Feature Engine库详解与实战

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 特征工程是机器学习中至关重要的一环&#xff0c;而Feature Engine库作为Python中的强大特征工程工具&#xff0c;提供了丰富的功能和灵活的操作。本文将深入探讨Feature Engine的各种特性&#xff0c;包括缺失值…

Trace 在多线程异步体系下传递

JAVA 线程异步常见的实现方式有&#xff1a; new ThreadExecutorService 当然还有其他的&#xff0c;比如fork-join&#xff0c;这些下文会有提及&#xff0c;下面主要针对这两种场景结合 DDTrace 和 Springboot 下进行实践。 引入 DDTrace sdk <properties><java.…

正确看待鸿蒙不兼容Android,这不是趋势?

华为可能明年推出不兼容安卓的鸿蒙版本。11月20日&#xff0c;据澎湃新闻报道&#xff0c;一华为相关人士表示&#xff0c;推出时间还不确定&#xff0c;未来IOS、鸿蒙、安卓将为三个各自独立的系统。 稍早前据证券时报报道&#xff0c;有业内人士亦表示&#xff1a;“华为内部…

eNSP小实验(vlan和单臂路由)

一.vlan的划分 实验目的&#xff1a; ①pc1 只可以和pc2通信&#xff0c;不可以和pc3 pc4通信 ②pc1和pc2只能到Server1&#xff0c;pc3和pc4到Server2 1.拓扑图 2.配置 PC1-4 同理配置 SW1 <Huawei> <Huawei>u t m //关闭注释 Info: …

三、Shell 环境

一、Linux 系统分类 在 Linux 中&#xff0c;常见的 Shell 有以下几种&#xff1a; Bourne Shell&#xff08;sh&#xff09;&#xff1a;最早的 Shell&#xff0c;由 Stephen Bourne 开发。它是大多数其他 Shell 的基础。Bourne Again Shell&#xff08;bash&#xff09;&am…

AI会取代文档工程师的工作吗?

▲ 搜索“大龙谈智能内容”关注GongZongHao▲ 先说结论&#xff0c;两个字&#xff1a;不会。 用四个字来说&#xff1a;恰恰相反。 人工智能&#xff08;AI&#xff09;在客户服务领域的应用在快速且不断地发展。围绕技术内容和知识在用户体验和客户支持中不可替代的作用的…

Centos7部署SVN

文章目录 &#xff08;1&#xff09;SVN概述&#xff08;2&#xff09;SVN与Samba共享&#xff08;3&#xff09;安装SVN&#xff08;4&#xff09;SVN搭建实例&#xff08;5&#xff09;pc连接svn服务器&#xff08;6&#xff09;svn图标所代表含义 &#xff08;1&#xff09;…

nvm 的使用 nvm 可以快速的切换 nodejs 的版本

nvm 是什么&#xff1f; nvm 是一个 node 的版本管理工具&#xff0c;可以简单操作 node 版本的切换、安装、查看。。。等等&#xff0c;与 npm 不同的是&#xff0c;npm 是依赖包的管理工具。 nvm 下载安装 安装之前需要先把 自己电脑上边的 node 给卸载了!!!! 很重要 下载地…

2023前端面试题总结:JavaScript篇完整版

前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 JavaScript基础知识 JavaScript有哪些数据类型&#xff0c;它们的区别&#xff1f; Number&#xff08;数字&#xff09;: 用于表示数值&#xff0c;可…

js 转换为数组并返回(Array.of())

Array提供了方法直接将一组值转换为数组并返回 Array.of()方法 Array.of(1,2,3) 结果

【Let‘s Encrypt SSL】使用 acme.sh 给 Nginx 安装 Let’s Encrypt 提供的免费 SSL 证书

安装acme.sh 安装 acme.sh 并设置邮箱用来接受重要通知&#xff0c;如证书快过期未更新通知 curl https://get.acme.sh | sh -s emailmyexample.com执行命令后几秒就安装好了&#xff0c;如果半天没有反应请 CtrlC 后重新执行命令。acme.sh 安装在 ~/.acme.sh 目录下&#xf…

Vim 搜索多个关键字并高亮

在查看代码或日志的时候&#xff0c;经常会需要搜索某个关键字。VIM搜索时&#xff0c;会把关键字高亮显示&#xff0c;还是比较方便的。 可是&#xff0c;一个关键字往往是不够的&#xff0c;能否支持多个关键字查找呢&#xff1f;答案是肯定的。应该怎么操作呢&#xff1f; 其…

GIT的后悔药

版本回退 上篇咱们说过&#xff0c;GIT能够管理文件的历史版本&#xff0c;这也是版本控制器重要的能力。如果有一天你发现之前做的工作出现很大问题&#xff0c;需要在某个特定的历史版本重新开始&#xff0c;这个时候&#xff0c;就需要版本回退的功能了。执行git reset命令…

【数据结构(十二·图)】图的相关知识(包括深度优先遍历和广度优先遍历)

文章目录 1. 图的基本介绍1.1. 图的举例说明1.2. 图的常用概念 2. 图的表示方式2.1. 邻接矩阵2.2. 邻接表 3. 应用案例4. 图的遍历4.1. 深度优先遍历4.1.1. 基本思想4.1.2. 算法步骤4.1.3. 代码实现 4.2. 广度优先遍历4.2.1. 基本思想4.2.2. 算法步骤4.2.3. 代码实现 4.3. 图的…

跨域解决方案详解

文章目录 同源策略PostMessageWebsocket跨域资源共享&#xff08;CORS&#xff09;两种请求简单请求基本流程withCredentials 属性 需预检的请求预检请求预检请求的回应浏览器的正常请求和回应示例 Nginx反向代理Node中间件代理搭建node代理服务使用现成的node代理服务 JSONP前…