目录
一、访问路径(@RequestMapping)
1.1 访问路径注解作用域
1.2 路径精准(模糊)匹配
1.3 访问路径限制请求方式
1.4 进阶访问路径请求注解
1.5 与WebServlet的区别
二、接收请求数据
2.1 请求param参数
2.2 请求路径参数
2.3 请求Json数据参数格式
三、接收其它类型数据
3.2 接收请求头数据
3.3 原生Api对象操作
一、访问路径(@RequestMapping)
1.1 访问路径注解作用域
众所周知@RequestMapping注解是用于设置访问路径的,但是还需要了解其作用域。观看源码可以看到
RequestMapping可以作用在类和方法上,但是我们一般都是写在类的方法上,所以下面将举出具体例子介绍为什么会作用在类上。
案例:
@RestController
public class AppointmentController {
@RequestMapping("/appointment/Hello")
public String hello(){
System.out.println("Hello");
return null;
}
@RequestMapping("/appointment/Hi")
public String Hi(){
System.out.println("Hi");
return null;
}
@RequestMapping("/appointment/Bonjo")
public String Bonjo(){
System.out.println("Hello");
return null;
}
}
以上案例可以看到在一个Controller层中如果定义每一个方法路径下,都需要加上“/appointment”的父路径。当方法很多的时候就会非常麻烦,类上使用RequestMapping作用在于可以简化,类中方法的地址映射,相当于类映射/方法映射地址。
1.2 路径精准(模糊)匹配
除了前面的一些注解以外,@RequestMapping的路径有两种方式:1.模糊匹配 2.精准匹配
下面分别介绍模糊与精准匹配
1.模糊匹配
在@RequestMapping注解指定 URL 地址时,通过使用通配符,匹配多个类似的地址。
@Controller
public class ProductController {
/**
* 路径设置为 /product/*
* /* 为单层任意字符串 /product/a /product/aaa 可以访问此handler
* /product/a/a 不可以
* 路径设置为 /product/**
* /** 为任意层任意字符串 /product/a /product/aaa 可以访问此handler
* /product/a/a 也可以访问
*/
@RequestMapping("/product/*")
@ResponseBody
public String show(){
System.out.println("ProductController.show");
return "product show!";
}
}
单层匹配和多层匹配:
/*:只能匹配URL地址中的一层,如果想准确匹配两层,那么就写“/*/*”以此类推。
/**:可以匹配URL地址中的多层。
其中所谓的一层或多层是指一个URL地址字符串被“/”划分出来的各个层次
这个知识点虽然对于@RequestMapping注解来说实用性不大,但是将来配置拦截器的时候也遵循这个规则。
2.精准路径匹配
项目中最常用的就是精准路径匹配
所谓精准路径匹配是指在@RequestMapping注解指定 URL 地址时,不使用任何通配符,按照请求地址进行精确匹配。
案例代码:
@Controller
public class UserController {
/**
* 精准设置访问地址 /user/login
*/
@RequestMapping(value = {"/user/login"})
@ResponseBody
public String login(){
System.out.println("UserController.login");
return "login success!!";
}
/**
* 精准设置访问地址 /user/register
*/
@RequestMapping(value = {"/user/register"})
@ResponseBody
public String register(){
System.out.println("UserController.register");
return "register success!!";
}
}
1.3 访问路径限制请求方式
我们常见熟悉的请求方式有几种Get、Post、Delete、Put请求,有这么多种类请求,但是我们想要一种指定的请求方式该怎么办呢?请看源码中的method。
限制一种或者多种访问按照如下
@RestController
@RequestMapping("/vaccinum/appointment")
public class AppointmentController {
// TODO:通过设置参数中的方法进行限制,这里只能通过GET请求才能访问
@RequestMapping(value = "/Hello",method = RequestMethod.GET)
public String hello(){
System.out.println("Hello");
return null;
}
// TODO:对于限制仅允许多个请求种类只需要使用 "{ , , ...}"花括号括起来即可
@RequestMapping(value = "/Hi",method = {RequestMethod.POST,RequestMethod.GET})
public String Hi(){
System.out.println("Hi");
return null;
}
}
那么如果有用户用了限制以外的访问请求方式会怎么样呢?
答:如果用户用了限制以外的请求方式就会报错---405报错
注意: 博主这里用的是springboot中的springmvc,如果只是单纯的使用springmvc构建,那么就会报错,请在所有方法上多加一个注解@ResponseBody。
1.4 进阶访问路径请求注解
前面介绍了通过method参数进行限制requestMapping的请求方式,那么是否有更简单的方式实现限制访问请求呢?其实是有的,Spring框架中提供了几种快速请求种类映射
如下:
// 限制只能用Get
@GetMapping("对应路径")
// 限制只能用POST请求
@PostMapping("对应路径")
// 限制只能用Delete请求
@DeleteMapping("对应路径")
// 限制只能用Put请求
@PutMapping("对应路径")
这几种就是常用的请求映射,和一般的设置上method方法的,其实是等价的。
// TODO:下面两行代码是等价的
@RequestMapping(value = "/Hi",method = RequestMethod.GET)
@GetMapping("/Hi")
public String Hi(){
System.out.println("Hi");
return "Hi";
}
注意:如果使用了其中的一种注解,就不能够进行叠加使用了,如果想要叠加使用就需要回到原始的@RequestMapping并且设置参数method.{ , , , ...}
1.5 与WebServlet的区别
在使用注解@RequestMapping,并且学习过JavaWeb的同学,可能会对这个注解感到熟悉,这里的注解和Javaweb中的@WebServlet 注解似乎十分相似。那么他们有什么区别呢?
最主要的区别在于@WebServlet 其中的路径是必须加上"/"的。下面是博主JavaWeb文章中的一个案例代码,展示了@WebServlet注解中路径的配置。
而springmvc中的@RequestMapping的路径是可以不加" / " 的,这里将" / "全部去掉,再尝试能否访问到
二、接收请求数据
2.1 请求param参数
你可能对param参数并不太了解,但是其实日常上网中如果你留意到你的浏览器的地址,你会发现其实你经常有接触param这种参数。
地址?key=value&key2=value2....
例如 常见的百度:当你输入想要搜索的数据并点击确定时候,就可以看到地址栏的变化
这种就是param参数。
下面介绍param 和 json参数的比较:
参数编码:
param 类型的参数会被编码为 ASCII 码。例如,假设
name=john doe
,则会被编码为name=john%20doe
。而 JSON 类型的参数会被编码为 UTF-8。参数顺序:
param 类型的参数没有顺序限制。但是,JSON 类型的参数是有序的。JSON 采用键值对的形式进行传递,其中键值对是有序排列的。
数据类型:
param 类型的参数仅支持字符串类型、数值类型和布尔类型等简单数据类型。而 JSON 类型的参数则支持更复杂的数据类型,如数组、对象等。
嵌套性:
param 类型的参数不支持嵌套。但是,JSON 类型的参数支持嵌套,可以传递更为复杂的数据结构。
可读性:
param 类型的参数格式比 JSON 类型的参数更加简单、易读。但是,JSON 格式在传递嵌套数据结构时更加清晰易懂。
这里可以看到,虽然param的使用不如JSON数据,在于几个方面,
- 第一是可读性较低。
- 第二是不支持复杂的数据传输。
- 第三,读取的参数是无序的。并不像Json一样有特定的格式。
- 第四、Param只能存放字符串类型的数据。
综上虽然缺点比较多,但是作为程序员需要能够处理所有的数据类型。所以下面介绍如何读取Param类型数据。
1.直接取值
@RequestMapping("Hello")
// TODO:通过形参直接获取值
public String hello(String name,String sex){
System.out.println("Hello");
return "Hello";
}
通过形参直接获取值,但是请注意如果使用形参获取值,那么请求的数据名称必须一 一对应才能正常接收值。
如果不对应的情况下对应的数据会为null
2.通过注解@RequestParam获取值
前面可以看到如果形参之间如果名称并不对应的情况下是无法进行接受到数据的,而springmvc就提供了注解@RequestParam,可以给对应形参起别名,使用案例如下:
@RequestMapping("Hello")
// TODO:通过RequestParam 给形参起别名获取参数
public String hello(@RequestParam("name") String NAME,
@RequestParam("sex") String SEX){
System.out.println("name = " + NAME + ", sex = " + SEX);
return "name = " + NAME + ", sex = " + SEX;
}
可以看到正常返回了,方法中的形参都是SEX,NAME 大写的形式,而这里使用的是小写的形式。但是用了该注解需要注意以下几个点
1.使用注解后,默认对应的参数必须传递,不能为空。如果为空则会发生下面的情况
2.可以通过参数的设置实现取消默认为空的形式,即允许传递对应的数据为空的情况。在源码中可以看到对应参数。
@RequestMapping("Hello")
// TODO:设置不需要必须传递参数
public String hello(@RequestParam(value = "name") String NAME,
@RequestParam(value = "sex",required = false) String SEX){
System.out.println("name = " + NAME + ", sex = " + SEX);
return "name = " + NAME + ", sex = " + SEX;
}
运行案例即可看到现在正常访问了
3.通过设置默认值时候,必须传递的参数就默认不需要
直接不传递参数,直接访问路径
3.特殊情况接收值
1.一名多值:即一个key对应多个值,例如以下:
key = value1&key = value2key = value3...
对于这种多选框,提交的数据的时候一个key对应多个值,我们可以使用集合进行接收!
案例代码:
/**
* 前端请求: http://localhost:8080/param/mul?hbs=吃&hbs=喝
*
* 一名多值,可以使用集合接收即可!但是需要使用@RequestParam注解指定
*/
@GetMapping(value="/mul")
@ResponseBody
public Object mulForm(@RequestParam List<String> hbs){
System.out.println("hbs = " + hbs);
return hbs;
}
2.实体接收
Spring MVC 是 Spring 框架提供的 Web 框架,它允许开发者使用实体对象来接收 HTTP 请求中的参数。通过这种方式,可以在方法内部直接使用对象的属性来访问请求参数,而不需要每个参数都写一遍。下面是一个使用实体对象接收参数的示例:
定义一个用于接收参数的实体类:
public class User {
private String name;
private int age = 18;
// getter 和 setter 略
}
在控制器中,使用实体对象接收,示例代码如下:
@Controller
@RequestMapping("param")
public class ParamController {
@RequestMapping(value = "/user", method = RequestMethod.POST)
@ResponseBody
public String addUser(User user) {
// 在这里可以使用 user 对象的属性来接收请求参数
System.out.println("user = " + user);
return "success";
}
}
注意:在上述代码中,将请求参数name和age映射到实体类属性上!要求属性名必须等于参数名!否则无法映射!
2.2 请求路径参数
请求路径参数,可能没有听说过。其实格式类似下面
/user/name/password
上述格式的一个案例:/user/root/123456
其实就是name = root , password = 123456.
知道请求路径的格式了,那么应该如何进行接收呢?其实springmvc中为路径类提供了专门的注解。可以看到以下案例:
/**
* 动态路径设计: /user/{动态部分}/{动态部分} 动态部分使用{}包含即可! {}内部动态标识!
* 形参列表取值: @PathVariable Long id 如果形参名 = {动态标识} 自动赋值!
* @PathVariable("动态标识") Long id 如果形参名 != {动态标识} 可以通过指定动态标识赋值!
*
* 访问测试: /param/user/1/root -> id = 1 uname = root
*/
@GetMapping("/user/{id}/{name}")
@ResponseBody
public String getUser(@PathVariable Long id,
@PathVariable("name") String uname) {
System.out.println("id = " + id + ", uname = " + uname);
return "user_detail";
}
其中有几处与之前不同,如下:
1.动态路径设计: /user/{动态部分}/{动态部分}
2.参数:参数改为了@PathVariable
实践一下:
@RequestMapping("Hello/{name}/{sex}")
public String hello(@PathVariable String name, @PathVariable String sex) {
System.out.println("name = " + name + ", sex = " + sex);
return "name = " + name + ", sex = " + sex;
}
注意:
@PathVariable
注解中的参数名称应该和@RequestMapping
中的路径变量名称保持一致。由于 Java 是大小写敏感的,因此在@PathVariable
注解中使用大写的参数名可能会导致匹配失败。
2.3 请求Json数据参数格式
后端在不引用其它库的情况下进行接收json数据效率会十分低下或者直接报错,因为json数据是前端的一种实体对象。而后端并不存在该实体对象,所以进行接收的时候可能会出现问题。所以为了接收json格式字符串。通常需要引入工具类或者库。这里采用了阿里巴巴的fastjson的jar包以实现接收json格式的数据。
在项目中pom.xml中引入jar包
<!-- 阿里巴巴处理json的jar包-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.70</version>
</dependency>
fastjson的功能:
解析JSON:
parseObject(String text)
:将JSON格式的字符串解析为JSONObject。parseArray(String text)
:将JSON格式的字符串解析为JSONArray。生成JSON:
toJSONString(Object object)
:将Java对象序列化为JSON字符串。toJSONString(Object object, SerializerFeature... features)
:支持传入序列化特性,例如SerializerFeature.PrettyFormat
用于格式化输出。序列化特性:
SerializerFeature.PrettyFormat
:格式化输出JSON。SerializerFeature.WriteMapNullValue
:是否输出值为null的字段。SerializerFeature.WriteDateUseDateFormat
:使用日期格式化输出日期。反序列化特性:
Feature.AllowUnQuotedFieldNames
:允许非引号字段名。Feature.AllowSingleQuotes
:允许单引号包裹的字符串。自定义序列化和反序列化:
- 可以通过实现特定接口或注解来实现对特定类型的自定义序列化和反序列化。
特定对象处理:
TypeReference
:用于处理泛型类型的对象。
使用fastjson接收json数据案例:
@RequestMapping("/JsonTest")
// TODO:通过设置响应体注解@RequestBody实现接收json数据
public String Json(@RequestBody JSONObject jsonObject){
System.out.println("成功接受到JSON数据");
return "返回接收到的JSON数据为:"+jsonObject.toJSONString();
}
博主这里使用APIFOX软件的json数据传输,进行传递
三、接收其它类型数据
3.1 接收cookie参数
接收Cookie参数时候,需要确保对应的CookieName才能获取到对应的cookie。而Cookie一般通过注解@CookieValue("CookieName") 进行获取。看以下案例
// 设置cookie
@RequestMapping("/save")
public String CookieTest(HttpServletResponse servletResponse){
Cookie cookie = new Cookie("CookieTestName","AlphaMilk");
servletResponse.addCookie(cookie);
System.out.println("成功设置好cookie");
return "设置cookie成功";
}
// 获取cookie
@RequestMapping("/GetCookie")
public String GetCookie(@CookieValue("CookieTestName") String value){
return "获取到的Cookie值为"+value;
}
进入设置,设置cookie
再进行访问cookie对应的资源
3.2 接收请求头数据
由于请求头中有许多的数据,所以这里展示接收请求HOST(Host字段通常是指代目标服务器的域名或主机名)字段的内容,其它获取方式都是同理。
而获取请求头的方式也很简单,通过注解@RequestHeader("HeadName") 即可
案例:
@RequestMapping("/Header")
public String GetHead(@RequestHeader("HOST") String value){
return "获取到的HOST值为"+value;
}
3.3 原生Api对象操作
下表描述了支持的控制器方法参数
参数类型 | 描述 |
---|---|
jakarta.servlet.ServletRequest , jakarta.servlet.ServletResponse | 请求/响应对象 |
jakarta.servlet.http.HttpSession | 强制存在会话。因此,这样的参数永远不会为 null 。 |
java.io.InputStream , java.io.Reader | 用于访问由 Servlet API 公开的原始请求正文。 |
java.io.OutputStream , java.io.Writer | 用于访问由 Servlet API 公开的原始响应正文。 |
@PathVariable | 接收路径参数注解 |
@RequestParam | 用于访问 Servlet 请求参数,包括多部分文件。参数值将转换为声明的方法参数类型。 |
@RequestHeader | 用于访问请求标头。标头值将转换为声明的方法参数类型。 |
@CookieValue | 用于访问 Cookie。Cookie 值将转换为声明的方法参数类型。 |
@RequestBody | 用于访问 HTTP 请求正文。正文内容通过使用 HttpMessageConverter 实现转换为声明的方法参数类型。 |
java.util.Map , org.springframework.ui.Model , org.springframework.ui.ModelMap | 共享域对象,并在视图呈现过程中向模板公开。 |
Errors , BindingResult | 验证和数据绑定中的错误信息获取对象! |
获取原生对象示例:
/**
* 如果想要获取请求或者响应对象,或者会话等,可以直接在形参列表传入,并且不分先后顺序!
* 注意: 接收原生对象,并不影响参数接收!
*/
@GetMapping("api")
@ResponseBody
public String api(HttpSession session , HttpServletRequest request,
HttpServletResponse response){
String method = request.getMethod();
System.out.println("method = " + method);
return "api";
}
文章整合:
一、访问路径(@RequestMapping)
1.1 访问路径注解作用域
- @RequestMapping注解用于定义控制器处理请求的方法,可在类级别和方法级别上使用。
1.5 路径精准(模糊)匹配
- 可以通过@RequestMapping的value属性设置精准匹配的路径,或者通过使用ant风格的路径模式实现模糊匹配。
1.2 访问路径限制请求方式
- @RequestMapping注解的method属性可以限制请求的HTTP方法类型,确保方法只处理特定类型的请求。
1.3 进阶访问路径请求注解
- 除了@RequestMapping,还可以使用@GetMapping、@PostMapping、@PutMapping等注解来更直观地表达请求的HTTP方法类型。
1.4 与WebServlet的区别
- @RequestMapping是Spring MVC的注解,而@WebServlet是Servlet 3.0规范中的注解。@RequestMapping相比@WebServlet功能更为强大,支持更多的请求映射和参数配置。
二、接收请求数据
2.1 请求param参数
- 使用@RequestParam注解可以获取请求中的参数,并映射到方法的参数上。
2.2 请求路径参数
- 通过@PathVariable注解可以接收RESTful风格的路径参数。
2.3 请求Json数据参数格式
- 使用@RequestBody注解可以将请求中的JSON数据映射到方法的参数对象上。
三、接收其他类型数据
3.1 接收cookie参数
- 使用@CookieValue注解可以获取请求中的cookie数据。
3.2 接收请求头数据
- 通过@RequestHeader注解可以获取请求的头部信息。
3.3 原生Api对象操作
- 可以直接使用Servlet API中的对象,如HttpServletRequest、HttpServletResponse等,来操作原生的请求和响应数据。