【问题标题】:@RequestParam vs @PathVariable@RequestParam 与 @PathVariable
【发布时间】:2012-11-22 20:10:44
【问题描述】:

@RequestParam@PathVariable 在处理特殊字符时有什么区别?

+@RequestParam 接受为空格。

对于@PathVariable+ 被接受为+

【问题讨论】:

    标签: java spring spring-mvc


    【解决方案1】:

    如果 URL http://localhost:8080/MyApp/user/1234/invoices?date=12-05-2013 在 2013 年 12 月 5 日获取用户 1234 的发票,则控制器方法如下所示:

    @RequestMapping(value="/user/{userId}/invoices", method = RequestMethod.GET)
    public List<Invoice> listUsersInvoices(
                @PathVariable("userId") int user,
                @RequestParam(value = "date", required = false) Date dateOrNull) {
      ...
    }
    

    此外,请求参数可以是可选的,从 Spring 4.3.3 开始,路径变量 can be optional as well。但请注意,这可能会更改 URL 路径层次结构并引入请求映射冲突。例如,/user/invoices 是否会为用户 null 提供发票或 ID 为“发票”的用户的详细信息?

    【讨论】:

    【解决方案2】:

    可能是application/x-www-form-urlencoded midia类型将空格转为+,接收方将+转为空格。查看网址了解更多信息。http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1

    【讨论】:

      【解决方案3】:

      @RequestParam 注释用于从请求中访问查询参数值。查看以下请求 URL:

      http://localhost:8080/springmvc/hello/101?param1=10&param2=20
      

      在上面的 URL 请求中,param1 和 param2 的值可以访问如下:

      public String getDetails(
          @RequestParam(value="param1", required=true) String param1,
              @RequestParam(value="param2", required=false) String param2){
      ...
      }
      

      以下是@RequestParam注解支持的参数列表:

      • defaultValue - 如果请求没有该值或为空,这是作为回退机制的默认值。
      • name – 要绑定的参数的名称
      • required – 参数是否强制。如果为真,则未能发送该参数将失败。
      • value – 这是 name 属性的别名

      @PathVariable

      @PathVariable 标识用于传入请求的 URI 中的模式。让我们看看下面的请求 URL:

      http://localhost:8080/springmvc/hello/101?param1=10&param2=20

      上面的 URL 请求可以写在你的 Spring MVC 中如下:

      @RequestMapping("/hello/{id}")    public String getDetails(@PathVariable(value="id") String id,
          @RequestParam(value="param1", required=true) String param1,
          @RequestParam(value="param2", required=false) String param2){
      .......
      }
      

      @PathVariable注解只有一个属性值用于绑定请求URI模板。允许在单个方法中使用多个 @PathVariable 注释。但是,请确保只有一种方法具有相同的模式。

      还有一个更有趣的注解: @MatrixVariable

      http://localhost:8080/spring_3_2/matrixvars/stocks;BT.A=276.70,+10.40,+3.91;AZN=236.00,+103.00,+3.29;SBRY=375.50,+7.60,+2.07

      以及它的控制器方法

       @RequestMapping(value = "/{stocks}", method = RequestMethod.GET)
        public String showPortfolioValues(@MatrixVariable Map<String, List<String>> matrixVars, Model model) {
      
          logger.info("Storing {} Values which are: {}", new Object[] { matrixVars.size(), matrixVars });
      
          List<List<String>> outlist = map2List(matrixVars);
          model.addAttribute("stocks", outlist);
      
          return "stocks";
        }
      

      但您必须启用:

      <mvc:annotation-driven enableMatrixVariables="true" >
      

      【讨论】:

      • 一个字符串,例如userName 是否有类型参数?我倾向于使它成为一个变量,但它也可以是一个参数。
      • 可以在不使用@RequestMapping的情况下声明@PathParam@RequestParam
      【解决方案4】:
      @PathVariable - must be placed in the endpoint uri and access the query parameter value from the request
      @RequestParam - must be passed as method parameter (optional based on the required property)
       http://localhost:8080/employee/call/7865467
      
       @RequestMapping(value=“/call/{callId}", method = RequestMethod.GET)
       public List<Calls> getAgentCallById(
                  @PathVariable(“callId") int callId,
                  @RequestParam(value = “status", required = false) String callStatus) {
      
          }
      
      http://localhost:8080/app/call/7865467?status=Cancelled
      
      @RequestMapping(value=“/call/{callId}", method = RequestMethod.GET)
      public List<Calls> getAgentCallById(
                  @PathVariable(“callId") int callId,
                  @RequestParam(value = “status", required = true) String callStatus) {
      
      }
      

      【讨论】:

        【解决方案5】:

        @RequestParam 用于查询参数(静态值),例如:http://localhost:8080/calculation/pow?base=2&ext=4

        @PathVariable 用于动态值,例如:http://localhost:8080/calculation/sqrt/8

        @RequestMapping(value="/pow", method=RequestMethod.GET)
        public int pow(@RequestParam(value="base") int base1, @RequestParam(value="ext") int ext1){
            int pow = (int) Math.pow(base1, ext1);
            return pow;
        }
        
        @RequestMapping("/sqrt/{num}")
        public double sqrt(@PathVariable(value="num") int num1){
            double sqrtnum=Math.sqrt(num1);
            return sqrtnum;
        }
        

        【讨论】:

          【解决方案6】:

          1)@RequestParam用于提取查询参数

          http://localhost:3000/api/group/test?id=4
          
          @GetMapping("/group/test")
          public ResponseEntity<?> test(@RequestParam Long id) {
              System.out.println("This is test");
              return ResponseEntity.ok().body(id);
          }
          

          @PathVariable 用于直接从 URI 中提取数据:

          http://localhost:3000/api/group/test/4
          
          @GetMapping("/group/test/{id}")
          public ResponseEntity<?> test(@PathVariable Long id) {
              System.out.println("This is test");
              return ResponseEntity.ok().body(id);
          }
          

          2) @RequestParam 在数据主要通过查询参数传递的传统 Web 应用程序中更有用,而@PathVariable 更适合 URL 包含值的 RESTful Web 服务。

          3) 如果查询参数不存在或为空,@RequestParam 注释可以指定 默认值,使用 defaultValue 属性,前提是必需的属性是 false

          @RestController
          @RequestMapping("/home")
          public class IndexController {
          
              @RequestMapping(value = "/name")
              String getName(@RequestParam(value = "person", defaultValue = "John") String personName) {
                  return "Required element of request param";
              }
          
          }
          

          【讨论】:

          【解决方案7】:

          两个注解的行为方式完全相同。

          只有 2 个特殊字符 '!'和 '@' 被 @PathVariable 和 @RequestParam 注释所接受。

          为了检查和确认行为,我创建了一个仅包含 1 个控制器的 Spring Boot 应用程序。

           @RestController 
          public class Controller 
          {
              @GetMapping("/pvar/{pdata}")
              public @ResponseBody String testPathVariable(@PathVariable(name="pdata") String pathdata)
              {
                  return pathdata;
              }
          
              @GetMapping("/rpvar")
              public @ResponseBody String testRequestParam(@RequestParam("param") String paramdata)
              {
                  return paramdata;
              }
          }
          

          点击以下请求我得到了相同的响应:

          1. localhost:7000/pvar/!@#$%^&*()_+-=[]{}|;':",./?
          2. localhost:7000/rpvar?param=!@#$%^&*()_+-=[]{}|;':",./?

          !@ 在两个请求中都作为响应收到

          【讨论】:

            【解决方案8】:

            @RequestParam:我们可以说它是查询参数,就像一个键值对 @PathVariable:-它来自URI

            【讨论】:

            • 格式化代码sn-ps提高可读性
            猜你喜欢
            • 2020-09-16
            • 2014-08-16
            • 1970-01-01
            • 2015-08-28
            • 2015-08-18
            • 2017-11-10
            • 1970-01-01
            相关资源
            最近更新 更多