SpringBoot学习笔记【part11】Web开发——请求参数的注解

导读:本篇文章讲解 SpringBoot学习笔记【part11】Web开发——请求参数的注解,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

SpringBoot 学习笔记 Part11

1. @PathVariable(获取路径变量)

restful风格中,路径中传参不再使用 ?、& 和 key=value 形式了,而是使用 {value} 与 分隔符 / 来进行传递。

第一种方法是通过给 @PathVariable 的属性赋值来给形参变量进行映射。

@GetMapping("car/{id}/owner/{username}")
public Map<String, Object> getUser(@PathVariable("id") Integer id, @PathVariable("username") String name){
    Map<String,Object> map = new HashMap<>();
    map.put("id",id);
    map.put("name",name);
    return map;
}

第二种方法是使用@PathVariable标注一个形参Map< String , String > 。

@GetMapping("car/{id}/owner/{username}")
public Map<String, String> getUser(@PathVariable Map<String,String> pv){
    return pv;
}

html中写法为:

<a href="car/1/owner/zhangsan">testPathVariable</a>

2. @RequestHeader(获取请求头)

第一种方法是通过给 @RequestHeader 的属性赋值来给形参变量进行映射。

@GetMapping("testAnno")
public String testAnno(@RequestHeader("User-Agent") String agent){
    return agent;
}

第二种方式可以直接获取请求头集合,有3种方式:

  1. Map< String , String >
  2. MultiValueMap< String , String >
  3. HttpHeaders类型
@GetMapping("testAnno")
public Map<String, String> testAnno(@RequestHeader Map<String,String> headers){
    return headers;
}

3. @RequestParam(获取请求参数)

通过@RequestParam可以获取请求参数,即曾经我们web原生开发中使用的request.getParameter( String ParameterName )。

第一种方法是通过给 @RequestParam 的属性赋值来给形参变量进行映射。其中

@GetMapping("car/{id}/owner/{username}")
public Map<String, Object> testAnno(@RequestParam("age") Integer age, @RequestParam("inters")List<String> interests){
    Map<String ,Object> map = new HashMap<>();
    map.put("age",age);
    map.put("interests",interests);
    return map;
}

第二种方式可以直接标注一个Map< String , String >形参来获取请求参数的集合。注意:若有一个key有多个value值,则必须使用MultiValueMap< String , String >来接收。

@GetMapping("car/{id}/owner/{username}")
public Map<String, String> testAnno(@RequestParam MultiValueMap<String,String> params){
    String age = params.get("age");
    String interest1 = params.get("inters").get(0);
    String interest2 = params.get("inters").get(1);
    Map<String,String> map = new HashMap<String,String>();
    map.put("age",age);
    map.put("interest1",interest1);
    map.put("interest2",interest2);
    return map;
}

html中写法为:

<a href="car/1/owner/zhangsan?age=18&inters=football&inters=basketball">testRequestParam</a>

4. @CookieValue(获取cookie值)

第一种方法是通过给 @CookieValue 的属性赋值来给形参变量进行映射,形参为字符串类型。

@GetMapping("car/{id}/owner/{username}")
public Map<String, Object> testAnno(@CookieValue("_ga") String _ga){
    Map<String,Object> map = new HashMap<String, Object>();
    map.put("_ga",_ga);
    return map;
}

第二种方法是通过给 @CookieValue 的属性赋值来给形参变量进行映射,形参为 Cookie类型。

@GetMapping("car/{id}/owner/{username}")
public Map<String, Object> testAnno(@CookieValue("_ga") Cookie cookie){
    Map<String,Object> map = new HashMap<String, Object>();
    map.put(cookie.getName(),cookie.getValue());
    return map;
}

5. @RequestBody(获取请求体)

只有POST请求才有请求体,如表单提交。@RequestBody最多只能有一个,而@RequestParam()可以有多个。使用字符串类型的形参接受。

@PostMapping("save")
public String postMethod(@RequestBody String content){
    return content;
}

html中写法为:

<form action="save" method="post">
    用户名:<input type="text" name="username"><br>
    邮箱:<input type="text" name="email"><br>
    <input type="submit" value="提交">
</form>

6. @RequestAttribute(获取request域属性)

当我们进行请求转发时,我们一般会在request域中带属性一同转发。原生web开发时使用 request.getAttribute( ) 方法取出,而 SpringBoot 中提供了新的两种方式。

第一种方法是通过给 @RequestAttribute 的属性赋值来给形参变量进行映射,形参为字符串类型。

@Controller
public class RequestController {

    @GetMapping("goto")
    public String goToPage(HttpServletRequest request){
        request.setAttribute("msg","成功了...");
        request.setAttribute("code",200);
        return "forward:/success";
    }

    @ResponseBody
    @GetMapping("success")
    public Map successPage(@RequestAttribute("msg") String msg, @RequestAttribute("code") String code){
        Map<String,Object> map = new HashMap<>();
        map.put("request_msg",msg);
        map.put("request_code",code);
        return map;
    }
}

第二种方法是形参中加入原生 HttpServletRequest 类型接受转发器。

@Controller
public class RequestController {

    @GetMapping("goto")
    public String goToPage(HttpServletRequest request){
        request.setAttribute("msg","成功了...");
        request.setAttribute("code",200);
        return "forward:/success";
    }

    @ResponseBody
    @GetMapping("success")
    public Map successPage(HttpServletRequest request){
        Map<String,Object> map = new HashMap<>();
        map.put("request_msg",request.getAttribute("msg"));
        map.put("request_code",request.getAttribute("code"));
        return map;
    }
}

7. @MatrixVariable(获取矩阵变量)

根据RFC3986的规范,矩阵变量应当绑定在路径变量中。且在 springmvc 中,矩阵变量默认是禁用的,需要我们手动开启

前往springmvc底层源码,WebMvcAutoConfiguration类中的configurePathMatch()配置路径映射方法中,定义了一个UrlPathHelper类型的Url路径帮助器,UrlPathHelper里有个布尔类型的属性 private boolean removeSemicolonContent 是否移除分号内容,默认值是true。即removeSemicolonContent为true,路径里分号后面的内容都会被移除。

因此我们需要自定义一个UrlPathHelper组件。

第一种方法:使用@Bean注解把重写自定义组件方法的WebMvcConfigurer的接口实现类添加到容器中去,这样springmvc的自动配置类就不会自动生成默认的UrlPathHelper。

@Bean
public WebMvcConfigurer webMvcConfigurer(){
    return new WebMvcConfigurer() {
        @Override
        public void configurePathMatch(PathMatchConfigurer configurer) {
            UrlPathHelper urlPathHelper = new UrlPathHelper();
            urlPathHelper.setRemoveSemicolonContent(false);
            configurer.setUrlPathHelper(urlPathHelper);
        }
    };
}

第二种方法:由于@Configuration也是个组件会放到容器中去,因此我们可以让自定义配置类直接实现 WebMvcConfigurer 接口。由于jdk8有默认实现方法,因此我们只要重写那些我们需要自定义组件的方法即可。

@Configuration(proxyBeanMethods = false)
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        UrlPathHelper urlPathHelper = new UrlPathHelper();
        urlPathHelper.setRemoveSemicolonContent(false);
        configurer.setUrlPathHelper(urlPathHelper);
    }
}

我们之前学习的路径变量为 queryString类型(查询字符串),如:/car/{id}/owner/{username}?age=18&inters=football&inters=baskterball。矩阵变量则使用分号“;”进行变量的分割,若一个key有多个值时,用逗号“,”分隔,如:/car/sell;price=38;brand=byd,yd,audi 。

若要携带矩阵变量,那么在Controller方法中必须有url路径变量才能被解析(即url路径中需带有大括号{}格式的PathVariable路径变量)。

//访问测试url: http://localhost:8080/car/sell;price=100;brand=byd,yd
@GetMapping("car/{path}")
public Map carSell(@MatrixVariable("price") Integer price,@MatrixVariable("brand") List<String> brand){
    Map<String,Object> map = new HashMap<>();
    map.put("price",price);
    map.put("brand",brand);
    return map;
}

我们也可以用前面刚学的@PathVariable注解拿到对应的路径变量值。

//访问测试url: http://localhost:8080/car/sell;price=100;brand=byd,yd
@GetMapping("car/{path}")
public Map carSell(@PathVariable("path") String path,@MatrixVariable("price") Integer price,@MatrixVariable("brand") List<String> brand){
    Map<String,Object> map = new HashMap<>();
    map.put("path",path);
    map.put("price",price);
    map.put("brand",brand);
    return map;
}

当路径变量有多个时,我们需要给@MatrixVariable使用属性来加以区分。若不区分,则所有@MatrixVariable默认取第一个路径变量的矩阵变量。

//访问测试url: http://localhost:8080/boss/1;age=18/2;age=20
@GetMapping("boss/{bossId}/{empId}")
public Map carSell(@MatrixVariable(value = "age",pathVar = "bossId") Integer bossAge,
                   @MatrixVariable(value = "age",pathVar = "empId") Integer empAge){
    Map<String,Object> map = new HashMap<>();
    map.put("bossAge",bossAge);
    map.put("empAge",empAge);
    return map;
}

矩阵变量在未来的使用场景

当我们在session域中存储数据时,每次发送都会请求携带一个名为 jsessionid 的 cookie 来表示这个session。页面开发过程中,若cookie被禁用了,我们就拿不到session域中的内容了。此时就可以用矩阵变量的方式来传递,url重写如:/abc;jsessionid=xxx 。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/84472.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!