02 SpringMVC接收数据之访问路径设置+五种接参方式+@EnableWebMvc

1.1 访问路径设置

@RequestMapping注解的作用就是将请求的 URL 地址和处理请求的方式(handler方法)关联起来,建立映射关系。

SpringMVC 接收到指定的请求,就会来找到在映射关系中对应的方法来处理这个请求。

1.1.1 精准路径匹配

@Controller
public class UserController {

    /**
     * 精准设置访问地址 /user/login
     */
    @RequestMapping(value = {"/user/login"})
    @ResponseBody
    public String login(){
        System.out.println("UserController.login");
        return "login success!!";
    }

1.1.2 模糊路径匹配

在@RequestMapping注解指定 URL 地址时,通过使用通配符,匹配多个类似的地址。

@Controller
public class ProductController {

    /**
     *  路径设置为 /product/*  
     *    /* 为单层任意字符串  /product/a  /product/aaa 可以访问此handler  
     *    /product/a/a 不可以
     *  路径设置为 /product/** 
     *   /** 为任意层任意字符串  /product/a  /product/aaa 可以访问此handler  
     *   /product/a/a 也可以访问, /product/a/a/a还可以访问
     *  
     * 将来的配置拦截器也遵循这个规则
     */
    @RequestMapping("/product/*")
    @ResponseBody
    public String show(){
        System.out.println("ProductController.show");
        return "product show!";
    }
}

1.1.3 类和方法级的@RequestMapping

  1. 设置到类级别:@RequestMapping 注解可以设置在控制器类上,用于映射整个控制器的通用请求路径。这样,如果控制器中的多个方法都需要映射同一请求路径,就不需要在每个方法上都添加映射路径。
  2. 设置到方法级别:@RequestMapping 注解也可以单独设置在控制器方法上,用于更细粒度地映射请求路径和处理方法。当多个方法处理同一个路径的不同操作时,可以使用方法级别的 @RequestMapping 注解进行更精细的映射。
  3. 并且, 可以将两者结合优化代码的实现 :
//1.标记到handler方法
    @Controller
    public class UserController {
    
    @RequestMapping(value = {"/user/login"})
    @ResponseBody
    public String login(){
        System.out.println("UserController.login");
        return "login success!!";
    }
    
    @RequestMapping(value = {"/user/register"})
    @ResponseBody
    public String register(){
        System.out.println("UserController.register");
        return "register success!!";
    }
}


//2.优化标记类+handler方法
    //类上定位到/user
    @RequestMapping("/user")
    @Controller
    public class UserController {
    
    //handler方法上再进一步指明
    @RequestMapping(value = {"/login"})
    @ResponseBody
    public String login(){
        System.out.println("UserController.login");
        return "login success!!";
    }
    
    @RequestMapping(value = {"/register"})
    @ResponseBody
    public String register(){
        System.out.println("UserController.register");
        return "register success!!";
    }
}

1.1.4 请求方法限制

HTTP 协议定义了八种请求方式,在 SpringMVC 中封装到了下面这个枚举类:

public enum RequestMethod {
  GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
}
  • 默认情况下:@RequestMapping所注解的方法/类, 任何请求方式都可以对接过来!
  • 可以在在@RequestMapping中增加一个字段method=RequestMethod.xxx来指定请求方式 ,
  • 可同时指定多种请求方式 :
  • 违背请求方式,会出现405异常!!
@Controller
public class UserController {

    /**
     * 精准设置访问地址 /user/login
     * method = RequestMethod.POST 可以指定单个或者多个请求方式!
     * 注意:违背请求方式会出现405异常!
     */
    @RequestMapping(value = {"/user/login"} , method = RequestMethod.POST)
    @ResponseBody
    public String login(){
        System.out.println("UserController.login");
        return "login success!!";
    }

    /**
     * 指定多种请求方式
     */
    @RequestMapping(value = {"/user/register"},method = {RequestMethod.POST,RequestMethod.GET})
    @ResponseBody
    public String register(){
        System.out.println("UserController.register");
        return "register success!!";
    }

}

1.1.5 优化请求方法限制的代码 :

@RequestMapping 的 HTTP 方法特定快捷方式变体:

  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @DeleteMapping
  • @PatchMapping

注意:进阶注解只能添加到handler方法上,无法添加到类上!

@RequestMapping(value="/login",method=RequestMethod.GET)
||
@GetMapping(value="/login")

1.1.7 @GetMapping和@PostMapping :

  1. 安全性:
    涉及敏感数据或操作时,使用POST请求可能更安全。因为GET请求的参数直接暴露在URL中,可能会被记录在服务器日志或浏览器历史记录中,而POST请求的参数通常在请求体中,相对更安全。
  2. 请求体:
    如果操作需要接收复杂的请求体,例如JSON或表单数据,使用POST请求更为合适。POST请求的请求体可以用于传递较大或复杂的数据。
  3. RESTful设计原则:
    根据RESTful原则,GET请求用于读取资源,而POST请求用于创建或修改资源。

1.1.6常见问题 :

出现原因:多个 handler 方法映射了同一个地址,导致 SpringMVC 在接收到这个地址的请求时该找哪个 handler 方法处理。

There is already ‘demo03MappingMethodHandler’ bean method com.atguigu.mvc.handler.Demo03MappingMethodHandler#empGet() mapped.


1.2 接收参数

1.2.1 param和json参数比较

在 HTTP 请求中,我们可以选择不同的参数类型,如 param 类型和 JSON 类型。下面对这两种参数类型进行区别和对比:

  1. 参数编码:

    param 类型的参数会被编码为 ASCII 码。例如,假设 name=john doe,则会被编码为 name=john%20doe。而 JSON 类型的参数会被编码为 UTF-8。

  2. 参数顺序:

    param 类型的参数没有顺序限制。但是,JSON 类型的参数是有序的。JSON 采用键值对的形式进行传递,其中键值对是有序排列的。

  3. 数据类型:

    param 类型的参数仅支持字符串类型、数值类型和布尔类型等简单数据类型。而 JSON 类型的参数则支持更复杂的数据类型,如数组、对象等。

  4. 嵌套性:

    param 类型的参数不支持嵌套。但是,JSON 类型的参数支持嵌套,可以传递更为复杂的数据结构。

  5. 可读性:

    param 类型的参数格式比 JSON 类型的参数更加简单、易读。但是,JSON 格式在传递嵌套数据结构时更加清晰易懂。

总的来说,param 类型的参数适用于单一的数据传递,而 JSON 类型的参数则更适用于更复杂的数据结构传递。根据具体的业务需求,需要选择合适的参数类型。在实际开发中,常见的做法是:在 GET 请求中采用 param 类型的参数,而在 POST 请求中采用 JSON 类型的参数传递。


1.2.2 param参数接收

  1. 直接传值
    例如客户填写表单后 , 参数直接放在链接中传递:
    此时在handler中 , 只要形参名和类型都与传递参数一一对应.即可自动接收 :
@Controller
@RequestMapping("param")
public class ParamController {

    /**
     * 前端请求链接 : localhost:8080/param/value?name=你好age=18
     * 利用形参列表,直接接收前端传递的param参数!
     *    要求: 参数名 = 形参名
     * 
     *          类型相同
     * 出现乱码正常,json接收具体解决!!
     * @return 返回前端数据
     */
    @GetMapping(value="/value")
    @ResponseBody
    public String setupForm(String name,int age){
        System.out.println("name = " + name + ", age = " + age);
        return name + age;
    }
}

直接传值有一个显然的缺点 , 形参和传递参数并不一定同名且一一对应(例如用户干脆就不填age)

  1. @RequestParam注解传值 (仅可在形参列表中声明)

@RequestParam使用场景:

  • 指定绑定的请求参数名
  • 要求请求参数必须传递 (默认为必须传递)
  • 为请求参数提供默认值
 /**
 * 前端请求: http://localhost:8080/param/data?name=xx&stuAge=18
 * 
 *  使用@RequestParam注解标记handler方法的形参
 *  指定形参对应的请求参数@RequestParam(请求参数名称)
 */
@GetMapping(value="/data")
@ResponseBody
//通过@RequestPararm注解,指定传递参数name赋给形参name ,
//                      指定传递参数stuAge赋给形参age , 且修改为不必须传递 , 设定默认值18
public Object paramForm(@RequestParam(value = "name") String name, 
                        @RequestParam(value = "stuAge",required = false,defaultValue = "18") int age){

    System.out.println("name = " + name + ", age = " + age);
    //
    return name+age;
}

默认情况下,使用@RequestPararm注解的方法参数是必需的,但可以通过将 @RequestParam 注解的 required 标志设置为 false

  1. 特殊场景接值

a. 一名多值
需求 : 多选框,提交的数据的时候一个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;
  }

b. 实体接收

优点 : 可以在方法内部直接使用对象的属性来访问请求参数,而不需要每个参数都写一遍。
缺点 : 由于是通过对象传值 , 无法采用@RequestParam绑定形参和传递参数 , 因此二者的属性名必须要相同 . 即User类内部定义的是name和age,那么传递参数的名也必须是name和age.

定义一个用于接收参数的实体类:

public class User {

  private String name;

  private int age = 18;

  // getter 和 setter 略
}

在控制器中,使用实体对象接收,示例代码如下:

@Controller
@RequestMapping("param")
public class ParamController {

    @POSTMapping(value = "/user")
    @ResponseBody
    public String addUser(User user) {
        // 在这里可以使用 user 对象的属性来接收请求参数
        System.out.println("user = " + user);
        return "success";
    }
}

在上述代码中,将请求参数name和age映射到实体类属性上!要求属性名必须等于参数名!否则无法映射!

使用postman传递参数测试:


1.2.3 接收JSON参数(@RequestBody)

  • @RequestBody 注解来将 JSON 数据转换为 Java 对象
  • @RequestBody 注解表示当前方法参数的值应该从请求体中获取,并且需要指定 value 属性来指示请求体应该映射到哪个参数上
  1. 定义一个用来接收json数据的实体类
public class Person {
  private String name;
  private int age;
  private String gender;
  // getter 和 setter 略
}
  1. 前端发送 JSON 数据的示例:(使用postman测试)
{
  "name": "张三",
  "age": 18,
  "gender": "男"
}
  1. 在控制器中,使用 @RequestBody 注解来接收 JSON 数据,并将其转换为 Java 对象:
@PostMapping("/person")
@ResponseBody
public String addPerson(@RequestBody Person person) {

 // 在这里可以使用 person 对象来操作 JSON 数据中包含的属性
 return "success";
}

Java原生只支持param传参和路径传参 , json是前端定义的格式 .因此需要做两件事.
a. 导入json依赖
b.handlerAdapter配置json转化器(即在config类上增加@EnableWebMvc)

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.15.0</version>
</dependency>

此时运行程序 , 可以接收到传来的json。


插播一条@EnableWebMvc注解:

原本,MvcConfig类中,我们需要重写handlerMapping,handlerAdapter两个方法,上例中又加入了一个新需求即配置一个json转化器。然而这一切只需要MvcConfig上声明一个@EnableWebMvc注解即可实现。


1.2.4 路径参数接收(动态传参)

先理解是什么:

http://localhost:8080/user/login?account=root&password=12345
||
http://localhost:8080/user/root/12345
即将每个参数视为路径 , 这就是路径传参
  • 路径传递参数是一种在 URL 路径中传递参数的方式。在 RESTful 的 Web应用程序中,经常使用路径传递参数来表示资源的唯一标识符或更复杂的表示方式。
  • Spring MVC 框架提供了 @PathVariable 注解来处理路径传递参数 , 该注解允许将 URL 中的占位符映射到控制器方法中的参数。

例如,如果我们想将 /user/{id} 路径下的 {id} 映射到控制器方法的一个参数中,则可以使用 @PathVariable 注解来实现。

 /**
 * 动态路径设计: /user/{动态部分}/{动态部分}   动态部分使用{}包含即可! {}内部动态标识!
 * 形参列表取值: @PathVariable Long id  如果形参名 = {动态标识} 自动赋值!
 *              @PathVariable("动态标识") Long id  如果形参名 != {动态标识} 可以通过指定动态标识赋值!
 *              和RequestParama一样 , 通过value属性绑定两个属性(@PathVariable(value="stuAge") int age)
 */
 //动态路径设计, 可在形参列表获取传入的参数
@GetMapping("/user/{id}/{name}")
@ResponseBody
//形参列表获取参数, 分别传入上头的GetMapping和下面的方法
public String getUser(@PathVariable Long id, 
                      @PathVariable("name") String uname) {
    System.out.println("id = " + id + ", uname = " + uname);
    return "user_detail";
}
//访问测试:  /param/user/1/root 可得结果: id = 1  uname = root

1.2.5 数组接参

数组作为形参,接受多个参数值 ,此时参数显示在链接中
可用于接收多选

    @GetMapping("/param/vals")
    public String getMultiVal(Integer [] id){
        List<Integer> idList = Arrays.asList(id);
        return idList.toString();
    }

测试请求:

//两种方式都是接收成功
GET http://localhost:8080/param/vals?id=11&id=12&id=13
GET http://localhost:8080/param/vals?id=11,12,13,14,15
  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值