【SpringMVC】使用篇:SpringMVC的开始

news2024/12/24 20:26:41

目录
一、前言
二、@RequestMapping
三、params表达式
四、Ant风格资源地址
五、@PathVariable
六、Rest风格的请求数据
七、请求映射数据


相关文章

【SpringMVC】入门篇:带你了解SpringMVC的执行流程【SpringMVC】入门篇:带你了解SpringMVC的执行流程

一、前言

 在入门篇中,我们对SpringMVC做了简单的介绍。对它的执行流程有了大概的认识,我们从这节开始讲解它使用。

二、@RequestMapping

 在上节的演示中,我们使用到了@RequestMapping,这里我们对他做一个详解。了解它的作用是什么。

<form action="user/buy" method="get">
    购买人:<input type="text" name="username"><br>
    购买数量:<input type="text" name="nums"><br>
    <input type="submit" value="登录">
</form>
package com.jl.web;

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

/**
 * ClassName: UserHandler
 * Package: com.jl.web
 * Description: @RequestMapping的介绍使用
 *
 * @Author: Long
 * @Create: 2022/11/26 - 16:38
 * @Version: v1.0
 *
 */
@RequestMapping(value = "/user")
@Controller // 这就是一个控制器
public class UserHandler {
    @RequestMapping(value = "/buy")
    public String buy(){
        System.out.println("购买商品");
        return "success";
    }
}
  1. @RequestMapping可以在方法、类上使用。当然也可以组合使用。例如:我们上上边示例的访问路径就是:http://localhost:8080/web工程路径/user/buy
  2. @RequestMapping的参数中可以指定浏览器的请求方式。默认支持 POST 和 GET(即:不指定method参数的时候)。例:// @RequestMapping(value = "/buy",method = RequestMethod.POST)
  3. 通过 method 指定请求方式:最常用的有 POST、GET、DELETE、PUT。
  4. 如果前端的请求方式和后端指定的请求方式不一致,就会报405错误。
    "HTTP Status 405 - Request method 'GET' not supported"
    在这里插入图片描述
  5. 对于请求路径和请求方式都指定的时候,我们可以使用简化的一种注解:
    • @DeleteMapping:指定DELETE请求方式。
    • @PostMapping:指定POST请求方式。
    • @GetMapping:指定GET请求方式。
    • @PutMapping:指定Put请求方式。

三、params表达式

<h1>演示params的使用</h1>
<a href="user/find?bookId=100">查询书籍</a>
@RequestMapping(value = "/find",params = "bookId",method = RequestMethod.GET)
public String search(String bookId){
    System.out.println("购买书籍的ID为:" + bookId);
    return "success";
}
  1. params = “bookId” 表示请求该目标方法时,必须给一个bookId,但值没有限制。如果没有携带此参数,就会报错400。
  2. 并且此参数会自动赋值给 search(String bookId)。
  3. 如果 params = “bookId=100”,就必须要求参数值为100。如果值不为100就会报错。
  4. 也可以 params = “bookId!=100”,来限制参数不为某个值。

SpringMVC当你的形参名和请求参数名一样的使用,也会自动注入到形参中。也就是说我们可以不使用其他任何的注解,也可以注入到形参中。

四、Ant风格资源地址

 这个有点类似于我们以前学的通配符。
这里我们提出一个需求:同时匹配 /message/aa、/message/aa/bb/cc

<h1>Ant风格请求资源地址</h1>
<a href="user/message/aa">发送消息1</a>
<a href="user/message/aa/bb/cc">发送消息2</a>
@RequestMapping(value = "/message/**")
public String im(){
   System.out.println("发送消息");
   return "success";
}

@RequestMapping(value = “/message/**”)表示可以匹配多层路径

五、@PathVariable

 使用@PathVariable可以简化我们的资源请求地址。我们来将传统的方式简化之后的资源请求URI做一个对比:
传统方式:http://localhost:8080/web工程路径/资源地址?参数1=参数值1&参数2=参数值2
简化之后:http://localhost:8080/web工程路径/资源地址?参数值1/参数值2
当想要支持这种URI就得配合使用@PathVariable

<h1>占位符的演示</h1>
<a href="user/reg/mary/100">占位符的演示</a>
@RequestMapping(value = "/reg/{username}/{userid}")
public String register(@PathVariable("username") String name,
                       @PathVariable("userid") String id){
    System.out.println("username= " + name + " userid= " + id);
    return "success";
}
  1. 从他的注解就可以知道,它中文译为路径变量。就是说它是根据路径来获取参数,而不是根据参数名来获取的。
  2. {}里边的名称要和我们@PathVariable的参数值一致。他就会自动将获取到的参数值注入到添加注解的形参中。

六、Rest风格的请求方式

我们先来了解一下它是一个什么东西❓

Rest风格的请求方式,用请求方式来体现业务逻辑。

  1. GET:用来获取资源
  2. POST:用来新建资源
  3. DELETE:用来更新资源
  4. PUT:用来删除资源

后端一般通过表单来获取前端发送的参数,所以我们有以下几个需要处理的问题:

  1. 浏览器form表单只支持 get post,因此得到put/delete需要Spring提供的HiddenHttpMethodFilter。过滤器进行转换。可以将这些请求转换为标准的http方法,使得支持POST、PUT、DELETE、GET。
  2. HiddenHttpMethodFilter只可以对POST请求进行转换。
  3. 这个过滤器要在web.xml中配置。

配置文件中配置转换的过滤器

<!--配置过滤器,用于转换Rest风格的请求方式
        除了这个过滤器,还得在Spring配置文件中添加两个配置
-->
<filter>
   <filter-name>hiddenHttpMethodFilter</filter-name>
   <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
   <filter-name>hiddenHttpMethodFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

在Spring配置文件中添加需要的配置

<!--两个常用配置-->
<!--支持MVC的高级功能,比如JS303的校验,映射动态请求-->
<mvc:annotation-driven></mvc:annotation-driven>
<!--将springMVC不能处理的请求,交给tomcat处理,比如css,js-->
<mvc:default-servlet-handler/>

前端演示用到的代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>rest </title>
<%--    引入jquery--%>
    <script type="text/javascript" src="script/jquery.js"></script>
    <script type="text/javascript">
        $(function () { //当页面加载完成后,就执行=> 如果你完全忘记,去回顾我们讲过的jquery
            //给删除超链接绑定一个点击事件
            $("#deleteBook").click(function (){
                //我们自己定义给提交的行为
                // 将我们a标签中的超链接的值设置给form表单的action中,最后提交
                $("#hiddenForm").attr("action", this.href);
                $(":hidden").val("DELETE");
                $("#hiddenForm").submit();
                return false; //改变点击超链接的行为, 不在提交
            })
        })
    </script>
</head>
<body>
<h3>Rest风格的crud操作案例</h3>
<br><hr>

<h3>rest风格的url 查询书籍[get]</h3>
<a href="user/book/200">点击查询书籍</a>
<br><hr>

<h3>rest风格的url 添加书籍[post]</h3>
<form action="user/book" method="post">
    name:<input name="bookName" type="text"><br>
    <input type="submit" value="添加书籍">
</form>
<br><hr>

<h3>rest风格的url, 删除一本书[delete]</h3>
<a href="user/book/600" id="deleteBook">删除指定id的书</a>
<form action="" method="post" id="hiddenForm">
    <input type="hidden" name="_method"/>
</form>
<br><hr>

<h3>rest风格的url 修改书籍[put]</h3>
<form action="user/book/666" method="post">
    <input type="hidden" name="_method" value="PUT">
    <input type="submit" value="修改书籍~">
</form>
</body>
</html>

<a>标签是使用GET方式发送的请求,当我们想通过<a>标签来使用Rest风格的请求方式的时候,需要通过javaScrpit+Ajax来转成一个POST请求。我们的过滤器底层是通过参数_method来获取需要转换的类型,所以我们的请求参数里边得有_method=转换的类型

后端代码

package com.jl.web.rest;

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

/**
 * ClassName: BookHandler
 * Package: com.jl.web.rest
 * Description: 处理rest风格的请求-crud
 *
 * @Author: Long
 * @Create: 2022/11/26 - 18:40
 * @Version: v1.0
 */
@RequestMapping(value = "/user")
@Controller
public class BookHandler {

    @RequestMapping(value = "/book/{id}",method = RequestMethod.GET)
    public String getBook(@PathVariable("id")String id){
        System.out.println("查询的书籍的id= " + id);
        return "success";
    }

    @RequestMapping(value = "/book",method = RequestMethod.POST)
    public String addBook(String bookName){
        System.out.println("添加书籍的name= " + bookName);
        return "success";
    }

    // 删除[DELETE]
    @RequestMapping(value = "/book/{id}",method = RequestMethod.DELETE)
    public String delBook(@PathVariable("id") String id){
        System.out.println("删除书籍的id= " + id);
        // 这里会报一个405的错误【HTTP Status 405 - JSPs only permit GET POST or HEAD】
        // 因为JSP只支持 GET 和 POST 、HEAD请求。我们可以通过请求重定向的方式进行跳转。
//        return "success"; // 这是请求转发
        return "redirect:/user/success";
    }

    // 修改[put]
    @RequestMapping(value = "/book/{id}",method = RequestMethod.PUT)
    public String updateBook(@PathVariable("id") String id){
        System.out.println("修改书籍的id= " + id);
        return "redirect:/user/success";
    }

    // 如果是 user/success,就转发到 success.jsp
    @RequestMapping(value = "/success")
    public String successGeneral(){
        return "success";
    }
}

 到这里虽然我们已经演示完毕,但至于它到底是怎样执行的,我相信很多小伙伴还是一头雾水,下边我们来梳理一下,它底层的执行转换流程。

在这里插入图片描述

// 源码:
// HiddenHttpMethodFilter 会根据参数名为 "_method" 来获取它的参数,而此参数值是我们需要
// 转换的请求方式。
public static final String DEFAULT_METHOD_PARAM = "_method";

if ("POST".equals(request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) {
String paramValue = request.getParameter(this.methodParam);
if (StringUtils.hasLength(paramValue)) {
String method = paramValue.toUpperCase(Locale.ENGLISH);
if (ALLOWED_METHODS.contains(method)) {
requestToUse = new HttpMethodRequestWrapper(request, method);
}
}
}
//而且我们只会转换 ”POST“ 方式的请求。并且不是所有的都转换,转换的是包含在 ALLOWED_METHODS 里边的

private static final List<String> ALLOWED_METHODS =
   Collections.unmodifiableList(Arrays.asList(HttpMethod.PUT.name(),
           HttpMethod.DELETE.name(), HttpMethod.PATCH.name()));
//ALLOWED_METHODS里边只会将其转化为 DELETE、PUT、PATCH

七、请求映射数据

@RequestParam

 当我们的请求参数和形参名的定义不一致时,可以使用@RequestParam来实现参数的注入。

<h2>获取到超链接的值</h2>
<hr/>
<a href="vote/vote01?name=mary">获取超链接的参数</a>
@RequestMapping(value = "vote")
@Controller
public class VoteHandler {
    @RequestMapping(value = "/vote01")
    public String test01(@RequestParam(value = "name",required = false) String username){
        System.out.println("拿到的username = " + username);
        return "success";
    }
}
  1. @RequestParam(value = “name”)会获取到参数名为 name 的参数值。
  2. required = false 表示,此参数可以没有。默认是true,即:参数值不能为空
  3. @RequestParam会将获取到的参数值赋值给(String username)。
  4. 使用@RequestParam可以解决我们的前后端参数名不一致的情况。
  5. 使用了@RequestParamd之后,前端的参数名必须和@RequestParam的value保持一致。

@RequestHeader

 使用此注解可以获取到请求头信息。

<h2>获取请求头信息</h2>
<hr/>
<a href="vote/vote02">获取请求头信息</a>
</body>
/**
* 需求:获取请求头的参数
*/
@RequestMapping(value = "/vote02")
public String test02(@RequestHeader(value = "Accept-Encoding") String ae,
                    @RequestHeader(value = "Host") String host){
   System.out.println("Accept-Encoding = " + ae);
   System.out.println("Host = " + host);
   return "success";
}

获取JavaBean

 在SpringMVC中,可以将请求参数自动封装成一个对象。

<h2>添加主人信息</h2>
<hr/>
<form action="vote/vote03" method="post">
    主人编号<input type="text" name="id">
    主人姓名<input type="text" name="name">
    宠物号<input type="text" name="pet.id">
    宠物名<input type="text" name="pet.name">
    <input type="submit" value="提交">
</form>

对应的对象

package com.jl.web.requestparam.entity;

/**
 * ClassName: Monster
 * Package: com.jl.web.requestparam.entity
 * Description:
 *
 * @Author: Long
 * @Create: 2022/11/27 - 12:44
 * @Version: v1.0
 */
public class Master {
    private Integer id;
    private String name;
    private Pet pet;

    public Master(Integer id, String name, Pet pet) {
        this.id = id;
        this.name = name;
        this.pet = pet;
    }

    public Master() {
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Pet getPet() {
        return pet;
    }

    public void setPet(Pet pet) {
        this.pet = pet;
    }

    @Override
    public String toString() {
        return "Master{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", pet=" + pet +
                '}';
    }
}
@RequestMapping(value = "/vote03")
public String test03(Master master){
    System.out.println("主人的信息 = " + master);
    return "success";
}
  1. 方法的形参对应的类型来指定即可。SpringMVC会自动的进行封装。
  2. 如果是自动封装,提交的参数名必须要和对象的属性名保持一致。
  3. 如果属性是对象,这里仍然是通过 字段名.字段 = 值 就行。例如:pet.name进行提交即可(级联操作)。
  4. 如果提交的参数名和对象的属性名不一致,则对象的属性值就为null。

SevletyAPI的使用

 在SpringMVC中,它提供了我们原生的Servlet对象,供我们调用。

<h2>演示servlet API 的使用</h2>
<hr/>
<form action="vote/vote04" method="post">
    用户名:<input type="text" name="username"><br/>
    密码:<input type="text" name="password"><br/>
    <input type="submit" value="提交">
</form>
/**
 * 使用原生的Servlet的API。前提:要先引入相应的jar包:servlet-api.jar
 *
 */
@RequestMapping(value = "/vote04")
public String test04(HttpServletRequest request, HttpServletResponse response,HttpSession session){
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    System.out.println(username);
    System.out.println(password);

    // 补充:
    // 我们通过HttpSession形参传入和request获取的session是同一个对象。
    HttpSession session1 = request.getSession();
    System.out.println(session == session1);
    return "success";
}

 以上就是我们这节对于SpringMVC基本使用的讲解。下节我们对SpringMVC视图以及它的模型数据最进一步了解。

如果文章中有描述不准确或者错误的地方,还望指正。您可以留言📫或者私信我。🙏
最后希望大家多多 关注+点赞+收藏^_^,你们的鼓励是我不断前进的动力!!!
感谢感谢~~~🙏🙏🙏

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

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

相关文章

使用MMA解决拓扑优化问题的并行框架

使用MMA解决拓扑优化问题的并行框架 仅个人论文学习笔记。 本文的重点是用c实现的完全并行拓扑优化框架&#xff08;线性求解器和优化算法&#xff09;&#xff0c;将MMA(Method of Moving Asymptotes)优化算法并行化&#xff0c;作为代码的基本部分。 实现一个拓扑优化问题 在…

vitepress+gitee pages搭建自己的博客网站

概述 “不写博客的GISer不是一个好程序员”。所以&#xff0c;好多程序员会保留着写博客的习惯&#xff0c;一方面记录自己的学习成果或者解决某个问题的方法&#xff0c;一方面能够帮助到他人&#xff0c;再一方面也能够督促自己多学点东西……这是一个一举N得的事情。上为其…

【C语言进阶】怎么可能不会?十分钟带你玩转枚举与联合

目录 &#x1f34a;前言&#x1f34a;&#xff1a; &#x1f95d;一、枚举&#x1f95d;&#xff1a; 1.枚举类型的定义&#xff1a; 2.枚举类型的优点&#xff1a; 3.枚举类型的使用&#xff1a; &#x1f353;二、联合&#xff08;共用体&#xff09;&#x1f353;&#x…

【实验报告NO.000002】MIT 6.858 Computer System Security - Lab 3

0x03.Lab 3: Symbolic execution 本 lab 将教大家使用 符号执行 &#xff08;symbolic execution&#xff09; 这一强大的技术来寻找软件中的漏洞&#xff0c;在 lab 的最后我们将建立一个可以在 zoobar web 应用中寻找触发多种漏洞的符号执行系统&#xff08;准确的说是一个混…

基于主从博弈的电热综合能源系统动态定价与能量管理附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

你真的了解缓存吗?(2)

在上一篇文章你真的了解缓存吗?(1)中&#xff0c;我介绍了引入缓存的利与弊&#xff0c;以及在选择一款缓存中间件时应该注意什么。在这一篇文章中&#xff0c;我们继续介绍在不同的业务场景下&#xff0c;如何进行缓存的选择&#xff0c;具体来说就是缓存的分类&#xff0c;和…

嵌入式分享合集123

一、简易大功率变压器电路图 本文介绍的电子变压器克服了传统硅钢片变压器体积、重量大、效率低、价格高的缺点&#xff0c;电路成熟&#xff0c;性能稳定。 本电子变压器工作原理与开关电源相似&#xff0c;电路原理图见图1&#xff0c;由VD1-VD4将市电整流为直流&#xff0c…

书店管理系统(基于MySQL存储)

&#x1f388; 作者&#xff1a;Linux猿 &#x1f388; 简介&#xff1a;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;Linux、C/C、云计算、物联网、面试、刷题、算法尽管咨询我&#xff0c;关注我&#xff0c;有问题私聊&#xff01; &…

对标测评YD云电脑和天翼云电脑公众版

最近听说YD也推出了自研云电脑产品&#xff0c;抱着吃瓜心态网上充值体验了一把YD云电脑&#xff0c;正好我手上有天翼云电脑&#xff0c;凑一对测试看看两家央企在云计算领域的技术实力究竟如何。 测试环境搭建在我的个人pc上&#xff0c;分别下载YD云和天翼云电脑最新Windows…

[思维模式-3]:《如何系统思考》-3- 认识篇 - 什么是系统?系统的特征?

目录 第1章 什么是系统 1.1 万事万物都是一个有机的系统 1.2 系统的科学定义 1.3 系统的构成 1.4 系统的分类 第2章 动态复杂系统的八大特征 2.1 目的性 2.8 边界 2.3 结构影响行为 2.4 总体大于部分之和 2.5 因果互动 2.6 反馈 2.7 动态稳定性&#xff08;动态自…

SAP ABAP 小工具 获取两个日期时间秒数和输出时间转换文本

SAP ABAP 小工具 获取两个日期时间秒数和输出时间转换文本 引言&#xff1a; 小工具 获取两个日期时间秒数和输出时间转换文本&#xff0c;用于加强用户交互直观性。 关键字&#xff1a;SAP ABAP 日期时间间隔 秒数 转换时间文本 文章目录SAP ABAP 小工具 获取两个日期时间秒…

[附源码]Python计算机毕业设计Django吾悦商城管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

计算机毕业设计springboot+vue基本微信小程序的小区防疫监管系统

项目介绍 编写工具用idea 、Maven包,后端数据库是mysql,Java语言,springboot框架。其间,在健康打卡位置和物资选购要调用接口才可实现其功能。 1、研究对象&#xff1a;小区居民普通用户和小区管理员 管理员权限&#xff1a;管理员是整个系统的操作者,系统的各个模块都能进行信…

python中pandas进行数据分析与可视化(3)

1.创建数据源 在前几篇博客中&#xff0c;都是手动创建少量数据充当数据源&#xff0c;这次通过随机生成&#xff0c;让数据量多一些 # 导入所有需要的库 import pandas as pd import numpy.random as np import openpyxl import xlrd import matplotlib.pyplot as plt#创建一…

Python基础 - 本地模块的绝对导入/引用

目录 1. 项目入口文件 2. 绝对导入 Python本地模块的引入是比较简单的&#xff0c;包括绝对引用和相对引用(相对引用的博客参考下一篇Python基础 - 本地模块的相对导入/引用)&#xff0c;个人比较推荐使用绝对引用&#xff0c;会避免掉很多错误&#xff0c;本篇文章主要介绍绝…

【Javassist】快速入门系列01 使用Javassist实现Hello World

系列文章目录 01 使用Javassist实现Hello World 文章目录系列文章目录前言引入Javassist jar包使用Javassist实现Hello World总结说明前言 本篇文章为Javassist入门系列文章&#xff0c;适合了解Java基础语法的人零基础学会使用Javassist实现一个Hello World程序。 引入Javas…

国企招聘: 中国雄安集团2023校园招聘,面向全国,不限户籍

中国雄安集团有限公司2023年校园招聘公告 中国雄安集团有限公司&#xff08;以下简称“中国雄安集团”&#xff09;成立于2017年7月18日&#xff0c;是雄安新区开发建设的主要载体和运作平台。结合雄安新区建设需要&#xff0c;中国雄安集团布局金融与投资、城市发展与城市资源…

高低电平报警器-(模电、数电电子课程设计,毕业设计)Multisim仿真图

目录1 背景与意义1.1 研究背景1.2 研究内容1.3 技术指标2 电路设计2.1 各单元电路设计2.1.1 步进电源电路设计2.1.2 比较电路设计2.1.3 报警电路设计2.2 总体电路设计3 Multisim电路仿真与调试3.1仿真过程3.1.1 步进电源仿真调试3.1.2 总体电路仿真与调试3.2仿真结果分析4 总结…

Java项目:SSM婚纱影楼摄影商城项目网站

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 本项目分为前后台&#xff0c;前台为普通用户登录&#xff0c;后台为管理员登录&#xff1b; 管理员角色包含以下功能&#xff1a; 管理员登录…

R语言学习笔记——高级篇:第十四章-主成分分析和因子分析

R语言 R语言学习笔记——高级篇&#xff1a;第十四章-主成分分析和因子分析 文章目录R语言前言一、R中的主成分和因子分析二、主成分分析2.1、判断主成分的个数2.2、提取主成分2.3、主成分旋转2.4、获取主成分得分三、探索性因子分析3.1、判断需提取的公共因子数3.2、提取公共…