美文网首页
Spring MVC注解

Spring MVC注解

作者: 扎Zn了老Fe | 来源:发表于2018-10-13 12:01 被阅读0次

    在Springmvc的控制器中,经常会用到注解修饰参数,这里主要讲解常用的注解。
    先来熟悉下content-Type。在HTTP协议消息头中,使用Content-Type来表示请求和响应中的媒体类型信息。它用来告诉服务端如何处理请求的数据,以及告诉客户端(一般是浏览器)如何解析响应的数据,比如显示图片,解析并展示html等等。
    application/x-www-form-urlencoded
    HTTP会将请求参数用key1=val1&key2=val2的方式进行组织,并放到请求实体里面,注意如果是中文或特殊字符如"/"、","、“:" 等会自动进行URL转码。不支持文件,一般用于表单提交。
    下面是一个例子:

    • 请求参数


      application/x-www-form-urlencoded请求参数
    • http 请求报文


      application/x-www-form-urlencoded报文

    multipart/form-data
    与application/x-www-form-urlencoded不同,这是一个多部分多媒体类型。首先生成了一个 boundary 用于分割不同的字段,在请求实体里每个参数以------boundary开始,然后是附加信息和参数名,然后是空行,最后是参数内容。多个参数将会有多个boundary块。如果参数是文件会有特别的文件域。最后以------boundary–为结束标识。multipart/form-data支持文件上传的格式,一般需要上传文件的表单则用该类型。
    下面是一个例子:
    请求参数

    image.png
    http 请求报文
    image.png
    application/json
    JSON 是一种轻量级的数据格式,以“键-值”对的方式组织的数据。这个使用这个类型,需要参数本身就是json格式的数据,参数会被直接放到请求实体里,不进行任何处理。服务端/客户端会按json格式解析数据(约定好的情况下)。
    请求参数
    image.png
    http 请求报文
    image.png

    application/xml 和 text/xml
    与application/json类似,这里用的是xml格式的数据,text/xml的话,将忽略xml数据里的编码格式,参考。

    @RequestParam

    用来处理Content-Type: 为 application/x-www-form-urlencoded编码的内容,提交方式为GET或POST。GET和POST请求传的参数会自动转换赋值到@RequestParam 所注解的变量上。RequestParam实质是将Request.getParameter() 中的Key-Value参数Map利用Spring的转化机制ConversionService配置,转化成参数接收对象或字段。get方式中query String的值,和post方式中body data的值都会被Servlet接受到并转化到Request.getParameter()参数集中,所以@RequestParam可以获取的到。例如:
    login.jsp

    <form:form method="GET" action="/loginCheck" align="center">
        <table>
            <tr>
                账号:<input type="text" name="username" />
                </br>
            </tr>
            <tr>
                密码:<input type ="text" name = "userpasswd" />
                </br>
            </tr>
                    <input type="submit" value="登录"/><input type="reset" value="清空"/>
            </br>
            </tr>
        </table>
    </form:form>
    

    控制器

    @RequestMapping(value="/requestParamTest", method = RequestMethod.GET)
    public String requestParamTest(@RequestParam(value="username") String userName, @RequestParam(value="userpasswd") String userPasswd){
         System.out.println("requestParam Test");
         System.out.println("username: " + userName);
         System.out.println("userpasswd: " + userPasswd);
         return "hello";
     }
    

    也可以不使用@RequestParam,直接接收,此时要求controller方法中的参数名称要跟form中name名称一致。

    控制器

    @RequestMapping(value="/requestParamTest", method = RequestMethod.GET)
     public String requestParamTest(String username, String userpasswd){
         System.out.println("requestParam Test");
         System.out.println("username: " + username);
         System.out.println("userpasswd: " + userPasswd);
         return "hello";
     }
    

    @PathVariable

    通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过@PathVariable(xxx) 绑定到操作方法的入参中。例如:
    控制器

    @RequestMapping(value = "/partner/{partner_id}/poi/{poi_id}/contacts", method = RequestMethod.GET)
    @ResponseBody
    public void getContacts(@PathVariable("partner_id") String partner_id, @PathVariable("poi_id") String poi_id) {
           System.out.println("Hello");
      }
    

    url中定义了{partner_id}、{poi_id}两个占位符,参数中partner_id 和poi_id直接从url中路径中获取值。

    @RequestHeader

    顾名思义,这个注解是从HTTP header部分获取数据绑定到参数上面。header属性可以看https://blog.csdn.net/u014175572/article/details/54861813/
    代码块

    @Controller
    public class HelloController {
        @RequestMapping(value = "/hello.htm")
        public String hello(@RequestHeader(value="User-Agent") String userAgent) {
            //..
        }
    }
    

    @CookieValue

    显然, 用来获取Cookie中的值。
    代码块

    @RequestMapping("/getCookie")
     public String testCookie(@CookieValue(value="name",required=false) String name, @CookieValue(value="age",required=false) Integer age) {
         System.out.println(name+","+age);
         return "hello";
     }
    

    @RequestBody

    @RequestBody 注解则是将 HTTP 请求正文插入方法中,使用适合的 HttpMessageConverter 将请求体写入某个对象。该注解用于读取Request请求的body部分数据,使用系统默认配置HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上, 再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上。@requestBody注解常用来处理content-type不是默认的application/x-www-form-urlcoded编码的内容,比如说:application/json或者是application/xml等,一般情况下来说常用其来处理application/json类型。 在一些特殊情况@requestBody也可以用来处理content-type类型为application/x-www-form-urlcoded的内容,只不过这种方式不是很常用。@RequestBody接收的是一个Json对象的字符串,并绑定到参数上。
    前端

    $.ajax({
     url:"/login",
     type:"POST",
     data:'{"userName":"admin","pwd","admin123"}',
     contentType:"application/json charset=utf-8",
     success:function(data){
     alert("request success ! ");
     }
    });
    

    控制器

    @requestMapping("/login")
    public void login(@requestBody String userName,@requestBody String pwd){
      System.out.println(userName+" :"+pwd);
    }
    

    这种情况是将JSON字符串中的两个变量的值分别赋予了两个字符串。但是呢假如我有一个User类,拥有如下字段:String userName;String pwd;那么上述参数可以改为以下形式:@requestBody User user 这种形式会将JSON字符串中的值赋予user中对应的属性上。

    @ModelAttribute

    该注解有两个用法,一个是用于方法上,一个是用于参数上;
    用于方法上时: 通常用来在处理@RequestMapping之前,为请求绑定需要从后台查询的model;
    用于参数上时: 用来通过名称对应,把相应名称的值绑定到注解的参数bean上;
    @ModelAttribute的原理是
    ①. 调用 @ModelAttribute 注解修饰的方法(注解在方法上),实际上把 @ModelAttribute 方法中 Map 中的数据放在了 implicitModel 中.
    ②. 解析请求处理器的目标参数, 实际上该目标参数来自于 WebDataBinder 对象的 target 属性
    下面将举例说明不同的功能。
    用于方法上

     @Controller 
      public class HelloWorldController { 
          @ModelAttribute("user") 
          public User addAccount() { 
              return new User("jz","123"); 
           } 
      
          @RequestMapping(value = "/helloWorld") 
          public String helloWorld(@ModelAttribute("user") User user) { 
                user.setUserName("jizhou"); 
                return "helloWorld"; 
             } 
       }
    

    如上代码所示,在执行helloWorld方法前执行addAccount方法,构造map["user", User(”jz","123")]加入一个视图对象,这里因为没有明确表示对象名字将指定隐形对象。在执行helloWorld方法时, 参数中使用了@ModelAttribute注解,意思是从视图对象中获取user的属性值绑定到参数bean:user上 。这里多谈一句,如果在视图对象中没有找到user的属性值,则验证当前方法是否使用了 @SessionAttributes 进行修饰, 若使用了, 则尝试从 Session 中 获取 attrName 所对应的属性值 ; 若 session 中依然没有对应的属性值, 则抛出异常。其实很多场合不需要用@ModelAttribute也是能够绑定的。

    @RequestParam,@RequestBody, @ModelAttribute三者区别

    这三者使用频率较高,这里做个简单的总结:

    1. application/x-www-form-urlencoded,这种情况的数据@RequestParam、@ModelAttribute可以处理,@RequestBody也可以处理。@RequestParam绑定简单对象,@ModelAttribute和@RequestBody绑定复合对象。
    2. multipart/form-data,@RequestBody不能处理这种格式的数据。(form表单里面有文件上传时,必须要指定enctype属性值为multipart/form-data,意思是以二进制流的形式传输文件。)
    3. application/json、application/xml等格式的数据,必须使用@RequestBody来处理。

    @ResponseBody

    @Responsebody 注解表示该方法的返回的结果直接写入 HTTP 响应正文(ResponseBody)中,一般在异步获取数据时使用,通常是在使用 @RequestMapping 后,返回值通常解析为跳转路径,加上 @Responsebody 后返回结果不会被解析为跳转路径,而是直接写入HTTP 响应正文中。

    @SessionAttribute

    @ModelAttribute注解作用在方法上或者方法的参数上,表示将被注解的方法的返回值或者是被注解的参数作为Model的属性加入到Model中,然后Spring框架自会将这个Model传递给ViewResolver。Model的生命周期只有一个http请求的处理过程,请求处理完后,Model就销毁了。

    如果想让参数在多个请求间共享,那么可以用到要说到的@SessionAttribute注解。

    参考:
    [1]. https://blog.csdn.net/qq_14869093/article/details/86307084

    相关文章

      网友评论

          本文标题:Spring MVC注解

          本文链接:https://www.haomeiwen.com/subject/flloaftx.html