zoukankan      html  css  js  c++  java
  • mvc-bind-annotatioan

    RequestBody

    @RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的);GET方式无请求体,所以使用@RequestBody接收数据时,前端不能使用GET方式提交数据,而是用POST方式进行提交;如果后端参数是一个对象,且该参数前是以@RequestBody修饰的,那么前端传递json参数时,必须满足以下要求:

    • 后端@RequestBody注解对应的类在将HTTP的输入流(含请求体)装配到目标类(即:@RequestBody后面的类)时,会根据json字符串中的key来匹配对应实体类的属性,如果匹配一致且json中的该key对应的值符合(或可转换为),这一条我会在下面详细分析,其他的都可简单略过,但是本文末的核心逻辑代码以及几个结论一定要看! 实体类的对应属性的类型要求时,会调用实体类的setter方法将值赋给该属性。

    • json字符串中,如果value为""的话,后端对应属性如果是String类型的,那么接受到的就是"",如果是后端属性的类型是Integer、Double等类型,那么接收到的就是null。

    • json字符串中,如果value为null的话,后端对应收到的就是null。

    • 如果某个参数没有value的话,在传json字符串给后端时,要么干脆就不把该字段写到json字符串中;要么写value时, 必须有值,null  或""都行。千万不能有类似"stature":  ,这样的写法,如:

    @RequestBody与前端传过来的json数据的匹配规则

    声明:根据不同的Content-Type等情况,Spring-MVC会采取不同的HttpMessageConverter实现来进行信息转换解析

    全面的结论:

    结论①:@JsonAlias注解,实现:json转模型时,使json中的特定key能转化为特定的模型属性;但是模型转json时,
                   对应的转换后的key仍然与属性名一致,见:上图示例中的name字段的请求与响应。
                   以下图进一步说明:

                      此时,json字符串转换为模型时,json中key为Name或为name123或为name的都能识别。

    结论②:@JsonProperty注解,实现:json转模型时,使json中的特定key能转化为指定的模型属性;同样的,模
                   型转json时,对应的转换后的key为指定的key,见:示例中的motto字段的请求与响应。
                   以下图进一步说明:

                   此时,json字符串转换为模型时,key为MOTTO的能识别,但key为motto的不能识别。

    结论③:@JsonAlias注解需要依赖于setter、getter,而@JsonProperty注解不需要。

    结论④:在不考虑上述两个注解的一般情况下,key与属性匹配时,默认大小写敏感。

    结论⑤:有多个相同的key的json字符串中,转换为模型时,会以相同的几个key中,排在最后的那个key的值给模
                   型属性复制,因为setter会覆盖原来的值。见示例中的gender属性。

    结论⑥:后端@RequestBody注解对应的类在将HTTP的输入流(含请求体)装配到目标类(即:@RequestBody后面
                   的类)时,会根据json字符串中的key来匹配对应实体类的属性,如果匹配一致且json中的该key对应的值
                   符合(或可转换为)实体类的对应属性的类型要求时,会调用实体类的setter方法将值赋给该属性。

    https://blog.csdn.net/justry_deng/article/details/80972817

    RequestParam

    将请求参数绑定到你控制器的方法参数上

    语法:@RequestParam(value=”参数名”,required=”true/false”,defaultValue=””)

    RequestHeader

    @RequestHeader 是获取请求头中的数据,通过指定参数 value 的值来获取请求头中指定的参数值。其他参数用法和 @RequestParam 完全一样

    RequestMapping

    在Spring MVC 中使用 @RequestMapping 来映射请求,也就是通过它来指定控制器可以处理哪些URL请求,相当于Servlet中在web.xml中配置

    <servlet>
        <servlet-name>servletName</servlet-name>
        <servlet-class>ServletClass</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>servletName</servlet-name>
        <url-pattern>url</url-pattern>
    </servlet-mapping>

    的映射作用一致

    RequestPart

    @RequestPart这个注解用在multipart/form-data表单提交请求的方法上。支持的请求方法的方式MultipartFile,属于Spring的MultipartResolver类。这个请求是通过http协议传输的。

    类似于@RequestParam不过是用来接收文件的

    ResponseStatus

    此注解声明在方法、类上

    @Controller
    @RequestMapping(value = "/bind")
    public class BindController {
    
        /**
         * 用法一,标注在方法上
         * code reason value三种属性
         * value  和 code是一个含义, 默认值就是 服务器 500错误的 HttpStatus,作用就是改变服务器响应的状态码
         * reason是异常原因
         * @return
         */
        @ResponseStatus(code=HttpStatus.OK)//状态码200
        @RequestMapping(value = "/index")
        public String index() {
            return "index";
        }
    }

    https://www.cnblogs.com/lvbinbin2yujie/p/10575101.html

    CookieValue

    用来获取Cookie中的值

    参数:value:参数名称; required:是否必须  ;defaultValue:默认值

    @RequestMapping("/testCookie.action")
        public String testCookie(@CookieValue("JSESSIONID") String sessionId) {
            System.out.println("testCookieValue: sessionId: " + sessionId);
            return "msg";
        }

    DeleteMapping

    相当于@RequestMapping(value = "",method = RequestMethod.GET)

    GetMapping

    处理get请求,相当于@RequestMapping(value = "",method = RequestMethod.DELETE)

    PostMapping

    处理post请求,相当于@RequestMapping(value = "",method = RequestMethod.POST)

    PutMapping

    和PostMapping作用等同,都是用来向服务器提交信息。如果是添加信息,倾向于用@PostMapping,如果是更新信息,倾向于用@PutMapping。两者差别不是很明显

    PatchMapping

    Patch方式是对put方式的一种补充;

    put方式是可以更新.但是更新的是整体.patch是对局部更新;

    InitBinder

    作用一

    从字面意思可以看出这个的作用是给Binder做初始化的,被此注解的方法可以对WebDataBinder初始化。webDataBinder是用于表单到方法的数据绑定的!

    @InitBinder只在@Controller中注解方法来为这个控制器注册一个绑定器初始化方法,方法只对本控制器有效。

    @InitBinder
        public void initBinder(WebDataBinder binder, HttpServletRequest request) {
            System.out.println(request.getParameter("date"));
            binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("MM-dd-yyyy"), false));
        }

    上面是一个@InitBinder的简单用法, 其中binder.registerCustomEditor(Date.class,new CustomDateEditor(new SimpleDateFormat("MM-dd-yyyy"),false)); 这样一句话,作用就是将 自定义的MVC属性编辑器PropertyEditor 注册到当前binder的typeConverter的customEditors集合中,每一次请求和后端交互,每一个Controller方法入参都会创建一个Binder对象,binder对象相当于来完成请求和后端之间参数类型转换的职能类;  注意,每次请求都会创建新的binder对象,就是说上次请求的customEditors不可复用 , 每次执行都会添加到当前方法入参交互的binder的customEditors中,而且每次执行真正请求方法之前,会把 匹配上的@InitBinder标注的方法执行一遍才开始处理;

    当请求中参数和方法入参开始进行转换的时候,都会先使用自定义注册的PropertyEditor,会首先根据需要的类型去binder的typeConverter的typeConverterDelegate的propertyEditorRegistry的cutomEditors集合中查找,有点绕,先记录下,typeConverterDelegate的propertyEditorRegistry就是typeConverter对象本身, 所以就是去typeConverter对象的cutomEditors寻找自定义注册的属性编辑器,又回到了原点。 比如去customEditors中根据key为Date.class查找editor,  分为两种情况,一种是找到了合适的属性编辑器,调用其setValue、setAsText方法, 之后使用getValue就得到转换后的值,  得到了转换后的值,可能不是我们想要的类型,这时候就会使用 conversionService 重新来过,放弃之前的转换;  是我们想要的类型就直接返回转换后的值;  第二种情况是没找到合适的属性编辑器, 直接调用 ConversionService 进行转换工作;

    作用二

    binder.setFieldDefaultPrefix(fieldDefaultPrefix);

    将springmvc请求参数带有fieldDefaultPrefix前缀的参数,去掉该前缀再绑定到对应的参数上,个人觉得是为了区分具有相同名字的参数

    比如:

    @Setter
    @Getter
    @ToString  // 代码整洁所以使用lombok,可以自行百度
    public class Pojo {
        private String name;
        private String haircolor;
    }
     
    @Setter
    @ToString
    public class Pojo2 {
        private String name;
        private int age;
    }

    在两个对象上各使用@ModelAttribute,来给对象分别起别名, @Initbinder这里value属性指定 别名,然后给不同的参数加上了前缀 person. 、cat.  ;注意这里的两个 . 号 

        @RequestMapping("/test3")
       @ResponseBody
       public String test3(@ModelAttribute("person") Pojo person, @ModelAttribute("cat") Pojo2 cat){
           return "test Response Ok!"+person+","+cat;
       }
     
       @InitBinder("person")
       public void initPerson(WebDataBinder binder){
             binder.setFieldDefaultPrefix("person.");
       }
     
       @InitBinder("cat")
       public void initCat(WebDataBinder binder){
           binder.setFieldDefaultPrefix("cat.");
       }

    这样请求URL:………… test3?person.name=lvbinbin&cat.name=xiaobinggan&haircolor=black&age=20 这里前台改动的地方就是 person.name和 cat.name,而其他独有属性不需要前缀也可以对应赋给pojo、pojo2;  补充说明,@ModelAttribute注解不可以省略,通过这个取的别名来决定哪个@InitBinder对其生效;

    作用三

    WebDataBinder的setDisallowedFields(disallowedFields);

    SpringMvc接收请求参数时候,有些参数禁止的,不想接收,我也没遇到过啥情况禁止接收参数,这时候可以设置setDisallowedFields不接受参数

      @RequestMapping("/test4")
       @ResponseBody
       public String test4(@ModelAttribute("pojo2") Pojo2 pojo){
           return "test Response Ok!"+pojo;
       }
     
       @InitBinder("pojo2")
       public void disallowFlied(WebDataBinder binder){
           binder.setDisallowedFields("age");
       }

    另外补充一下,disallowedFields支持 * 通配符;

    @Initbinder的用法简而言之,就是Controller级别的属性编辑器,将请求中的String类型转为我们需要的参数,但是从效率、内存分析,感觉一直在创建新的属性编辑器集合,如果属性编辑器太多是不是会占用大量内存呢,那请求达到一定多的数量,这个对象是不是太多了呢?

    https://www.cnblogs.com/lvbinbin2yujie/p/10459303.html

    ModelAttribute

    注解方法

    被@ModelAttribute注释的方法会在此controller每个方法执行前被执行,因此对于一个controller映射多个URL的用法来说,要谨慎使用

    1.@ModelAttribute注释void返回值的方法

    @Controller
    public class HelloWorldController {
        @ModelAttribute
        public void populateModel(@RequestParam String abc, Model model) {
             model.addAttribute("attributeName", abc);
          }
    
        @RequestMapping(value = "/helloWorld")
        public String helloWorld() {
           return "helloWorld";
            }
     }

    这个例子,在获得请求/helloWorld 后,populateModel方法在helloWorld方法之前先被调用,它把请求参数(/helloWorld?abc=text)加入到一个名为attributeName的model属性中,在它执行后 helloWorld被调用,返回视图名helloWorld和model已由@ModelAttribute方法生产好了。

    2.@ModelAttribute注释返回具体类的方法

    @ModelAttribute 
    public Account addAccount(@RequestParam String number) { 
         return accountManager.findAccount(number); 
    } 

    这种情况,model属性的名称没有指定,它由返回类型隐含表示,如这个方法返回Account类型,那么这个model属性的名称是account。
    这个例子中model属性名称有返回对象类型隐含表示,model属性对象就是方法的返回值。它无须要特定的参数。

    这个注解标注在方法上表示往model里加,标注在参数上表示从model中取值

      @RequestMapping("/model.action")
        public String model(@ModelAttribute("car") Car car) {
    
            System.out.println(car);
            return "bind/model";
        }

    PathVariable

    映射 URL 绑定的占位符

    • 带占位符的 URL 是 Spring3.0 新增的功能,该功能在SpringMVC 向 REST 目标挺进发展过程中具有里程碑的意义
    • 通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过@PathVariable(“xxx“) 绑定到操作方法的入参中。
    • 主要是根据请求方法进行类的区别

    RequestAttribute

    用在方法参数上,从request中取值

    SessionAttribute

    用在方法参数上,从session中取值

    @RequestMapping("/path.action")
        public String session(@SessionAttribute("sessionStr")String sessionStr) {
            System.out.println(sessionStr);
            return "msg";
        }

    SessionAttributes

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

    通过@SessionAttributes注解设置的参数有3类用法:

    (1)在视图中通过request.getAttribute或session.getAttribute获取

    (2)在后面请求返回的视图中通过session.getAttribute或者从model中获取

    (3)自动将参数设置到后面请求所对应处理器的Model类型参数或者有@ModelAttribute注释的参数里面。

    将一个参数设置到SessionAttributes中需要满足两个条件:

    (1)在@SessionAttributes注解中设置了参数的名字或者类型

    (2)在处理器中将参数设置到了model中

    @SessionAttributes用户后可以调用SessionStatus.setComplete来清除,这个方法只是清除SessionAttribute里的参数,而不会应用Session中的参数。

    CrossOrigin

     https://blog.csdn.net/MobiusStrip/article/details/84849418

    MatrixVariable

    未知

    ControllerAdvice

     对于@ControllerAdvice,我们比较熟知的用法是结合@ExceptionHandler用于全局异常的处理,但其作用不仅限于此。ControllerAdvice拆分开来就是Controller Advice,关于Advice,前面我们讲解Spring Aop时讲到,其是用于封装一个切面所有属性的,包括切入点和需要织入的切面逻辑。这里ContrllerAdvice也可以这么理解,其抽象级别应该是用于对Controller进行“切面”环绕的,而具体的业务织入方式则是通过结合其他的注解来实现的。@ControllerAdvice是在类上声明的注解,其用法主要有三点:

    • 结合方法型注解@ExceptionHandler,用于捕获Controller中抛出的指定类型的异常,从而达到不同类型的异常区别处理的目的;
    • 结合方法型注解@InitBinder,用于request中自定义参数解析方式进行注册,从而达到自定义指定格式参数的目的;
    • 结合方法型注解@ModelAttribute,表示其标注的方法将会在目标Controller方法执行之前执行。

    关于这三种使用方式,需要说明的是,这三种注解如果应用于@ControllerAdvice注解所标注的类中,那么它们表示会对@ControllerAdvice所指定的范围内的接口都有效;如果单纯的将这三种注解应用于某个Controller中,那么它们将只会对该Controller中所有的接口有效,并且此时是不需要在该Controller上标注@ControllerAdvice的

    RestControllerAdvice

    如果返回值为接送,则使用这个注解,其他与ControllerAdvice没啥不同

    ExceptionHandler

    用来异常处理

       @RequestMapping("/exception.action")
        @ExceptionHandler({RuntimeException.class})
        public String exceptionhandler() {
            
            return "msg";
        }
  • 相关阅读:
    oracle登录错误(ORA-01033:ORACLE initialization or shutdown in progress
    mssql 判断sql语句的执行效率语句
    关于 knockout js 学习中的疑问 (1)
    JS 根据Url参数名称来获取对应的值 方法封装
    账户
    windows库
    CentOS的Qt3和Qt4问题
    c/c++调用dll
    CentOS 安装g++
    输入法不见了
  • 原文地址:https://www.cnblogs.com/QianYue111/p/13840723.html
Copyright © 2011-2022 走看看