SpringMVC : SpringMVC注解

家住魔仙堡 提交于 2020-01-20 12:34:13

1.美图

在这里插入图片描述

2.概述

Spring MVC相关注解 解释
@Controller 声明该类为SpringMVC中的Controller,用来处理http请求
@RestController 组合注解,@Controller + @ResponseBody.意味着,该Controller的所有方法都默认加上了@ResponseBody
@RequestMapping 把htt请求映射到方法上去
@PathVariable 用于接收路径参数,比如@RequestMapping(“/hello/{name}”)申明的路径,将注解放在参数中前,即可获取该值,通常作为Restful的接口实现方法
@RequestParam 将请求参数绑定至方法参数
@RequestBody 用于读取Request请求的body部分数据
@ResponseBody 将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区
@ModelAttribute 主要作用是绑定request或是form参数到模型(Model)
@InitBinder 用来设置WebDataBinder,WebDataBinder用来自动绑定前台请求参数到Model中
@ExceptionHandler 用于全局处理控制器里的异常
@ControllerAdvice 通过该注解,我们可以将对于控制器的全局配置放置在同一个位置,和@Controller对应
@RestControllerAdvice 同上和@RestController对应

3.@Controller

@Target({ElementType.TYPE}) // 该注解用于添加在方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {

    /**
     * 用于显示指定组件的名称
     * @Contorller 修饰的类对应的对象也是一个Bean,是一个注解,
     */
    @AliasFor(annotation = Component.class)
    String value() default "";

}

@Controller的作用很简单,就是表示添加了该注解的类是负责处理由DispatcherServlet 分发的http请求的。

4.@RestController

@RestController是一个组合注解,@Controller+@ResponseBody。关于@ResponseBody的解释,我们会在下文讲到。

5.@RequestMapping

@Target({ElementType.METHOD, ElementType.TYPE}) // 可以作用于类,接口,方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {

    /**
     * 为该映射起一个名字
     */
    String name() default "";

    /**
     * 指定请求的实际地址
     */
    @AliasFor("path")
    String[] value() default {};
    @AliasFor("value")
    String[] path() default {};

    /**
     * 指定请求的method类型, GET、POST、PUT、DELETE等
     */
    RequestMethod[] method() default {};

    /**
     * 指定request中必须包含某些参数值,才让该方法处理
     * 1. param1: 表示请求必须包含名为param1的请求参数
     * 2. !param1: 表示请求不能包含名为param1的请求参数
     * 3. param1!=value1: 表示请求包含名为param1的请求参数,但其值不能为 value1
     * 4. {"param1=value1", "param2"}: 请求必须包含名为 param1和param2的两个请求参数,且 param1参数的值必须为 value1
     */
    String[] params() default {};

    /**
     * 指定request中必须包含某些指定的header值,才能让该方法处理请求。
     * 比如, @RequestMapping(value = "/something", headers = "content-type=text/*")
     * 将会匹配所有请求里面包含 Content-Type of "text/html", "text/plain", etc.
     */
    String[] headers() default {};

    /**
     * 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html
     * Examples:
     * consumes = "text/plain"
     * consumes = {"text/plain", "application/*"}
     */
    String[] consumes() default {};

    /**
     * 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回
     * Examples:
     * <pre class="code">
     * produces = "text/plain"
     * produces = {"text/plain", "application/*"}
     * produces = MediaType.APPLICATION_JSON_UTF8_VALUE
     * </pre>
     */
    String[] produces() default {};

}

@RequestMapping是一个用来处理请求地址映射的注解。该注解可用于类或方法上,用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。@RequestMapping最终的目的就是把http对应的请求映射到对应的方法上。

6.@PathVariable

@Target(ElementType.PARAMETER) // 该注解用于添加在参数上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PathVariable {

    /**
     * Alias for {@link #name}.
     */
    @AliasFor("name")
    String value() default "";

    /**
     * 要绑定的路径变量的名称
     */
    @AliasFor("value")
    String name() default "";

    /**
     * 该属性是否是必须的,如果设置成必须的,但是路径里面没有传递该变量过来就抛出异常
     */
    boolean required() default true;

}

@PathVariable注解用于从url中获取数据。

7.@RequestParam

@Target(ElementType.PARAMETER) // 该注解只能加载参数上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {

    /**
     * 请求参数名
     */
    @AliasFor("name")
    String value() default "";
    @AliasFor("value")
    String name() default "";

    /**
     * 是否为必须参数
     */
    boolean required() default true;

    /**
     * 默认值,没有匹配到参数情况下的默认值
     */
    String defaultValue() default ValueConstants.DEFAULT_NONE;

}

@RequestParam用于将请求参数绑定至方法参数。

8.@RequestBody

@Target(ElementType.PARAMETER) // 该注解用于添加在参数上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestBody {

    /**
     * 该参数是否是必须的(是否非空)
     */
    boolean required() default true;

}

该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上。简单来说就是把Request请求对应的body数据映射成参数里面的对象。

9.@ResponseBody

@Target({ElementType.TYPE, ElementType.METHOD}) // 该注解用于添加在类或者方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseBody {

}

该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。

10.@ModelAttribute

@Target({ElementType.PARAMETER, ElementType.METHOD}) // 该注解用于添加在类或者方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ModelAttribute {

    /**
     * Alias for {@link #name}.
     */
    @AliasFor("name")
    String value() default "";

    /**
     * 要绑定的model属性的名称
     */
    @AliasFor("value")
    String name() default "";

    /**
     *
     * 允许直接在ModelAttribute方法参数或从ModelAttribute方法返回的属性上声明数据绑定,这两种方法都会阻止该属性的数据绑定。
     */
    boolean binding() default true;

}

@ModelAttribute注解的主要作用是绑定request或是form参数到模型(Model)对象。可以使用保存在requestsession中的对象来组装模型对象。注意,被@ModelAttribute注解的方法会在controller方法(@RequestMapping注解的)之前执行。因为模型对象要先于controller方法之前创建。

10.1 @ModelAttribute添加在方法上

ModelAttribute注解在方法上说明方法的作用是用于添加一个或多个属性到Model上。被@ModelAttribute注释的方法会在此Controller每个方法执行前被执行。因此对于一个Controller映射多个URL的用法来说,要谨慎使用。

10.2 @ModelAttribute添加在没有返回值的方法上

@ModelAttribute添加的方法没有返回值,一般这个时候我们需要自己去往Model里面添加数据了,要不然没啥意义。Model 就相当于每次请求的一个背包,我们可以往背包里面放东西。

	/**
     * Model: 就相当于每次请求的一个背包,我们可以往背包里面放东西
     */
    @ModelAttribute
    public void postVoidModelAttribute(@RequestParam String abc, Model model) {
        // 往model里面添加一个属性
        model.addAttribute("userId0", abc);
    }

10.3 @ModelAttribute添加在有返回值的方法上

@ModelAttribute添加在有返回值的方法上,会自动将该返回值放到Model里面去。

	/**
     * Model: 就相当于每次请求的一个背包,我们可以往背包里面放东西
     * @ModelAttribute 添加在有返回值的放的方法上,会把返回值放到Model里面去
     */
    @ModelAttribute(value = "userId1")
    public String postReturnModelAttribute(@RequestParam String abc) {
        return abc;
    }

10.4 @ModelAttribute添加在参数上

@ModelAttribute添加在参数上的时候用于从Model里面获取数据。上面我们已经通过把@ModelAttribute添加在方法上往Model里面添加了数据了,是时候取出来了。

/**
     * Model: 就相当于每次请求的一个背包,我们可以往背包里面放东西
     * 会在其他添加了@RequestMapping的方法之前执行
     */
    @ModelAttribute
    public void postVoidModelAttribute(@RequestParam String abc, Model model) {
        // 往model里面添加一个属性
        model.addAttribute("userId0", abc);
    }

    /**
     * Model: 就相当于每次请求的一个背包,我们可以往背包里面放东西
     * @ModelAttribute 添加在有返回值的放的方法上,会把返回值放到Model里面去
     * 会在其他添加了@RequestMapping的方法之前执行
     */
    @ModelAttribute(value = "userId1")
    public String postReturnModelAttribute(@RequestParam String abc) {
        return abc;
    }

    /**
     * 上面我们已经通过把@ModelAttribute添加在方法上往Model里面去了,这个时候我们可以通过把@ModelAttribute添加在参数上获取Model里面的值
     */
    @RequestMapping(value = "/text0")
    public String test0(@RequestParam String abc, @ModelAttribute("userId0") String userId) {
        System.out.println(userId);
        return "helloWorld";
    }

    /**
     * 其实我们也可以直接拿到Model
     */
    @RequestMapping(value = "/text1")
    public String helloWorld(@RequestParam String abc, Model model) {
        Map<String, Object> mapList = model.asMap();
        return "helloWorld";
    }

11.@InitBinder

Target({ElementType.METHOD}) // 该注解只能添加在方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface InitBinder {

    /**
     * value,作用是限制对哪些 @RequestMapping 方法起作用,
     * 具体筛选条件就是通过@RequestMapping方法入参来筛选,
     * 默认不写就代表对所有@RequestMapping的方法起作用。
     */
    String[] value() default {};

}

@InitBinder:用于给Binder做初始化,被@InitBinder注解的方法可以对WebDataBinder初始化。WebDataBinder是用于表单到方法的数据绑定的。只在添加了@InitBinder注解方法所在的控制器(Controller)里面有效。@InitBinder对应的方法在Controller的请求执行映射的方法之前被执行。同时添加了@InitBinder注解的方法返回值必须为null

我们用一个具体的实例来说明@InitBinder的用法,可能有这么个场景,关于时间部分我们调用接口的时候传递的是 “2019-09-05” 的格式,但是我们后天需要Date的格式。这个时候@InitBinder就派上大用场了呀,我们可以通过@InitBinder配合WebDataBinder的使用帮我们把 “2019-09-05” 转换成Date。

@RestController
@RequestMapping(path = "/initBinder")
public class InitBinderController {

    /**
     * 对当前控制器的所有请求都有效
     * 前台传递过来的String类型时间,通过下面的初始化绑定,转换成Date类型
     */
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        // 我们前台传过来的time字段对应的值可能是“2019-05-06”这样的,我们可以在这里把他们转换成Date类型的
        binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
    }


    @RequestMapping(value = "/test", method = RequestMethod.POST)
    public String helloWorld(@RequestBody InitBinderTestVo vo) {
        System.out.println(vo.getTime());
        return "success";
    }

}

12.@ExceptionHandler

@Target(ElementType.METHOD) // 标记该注解是添加在方法上的
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExceptionHandler {

    /**
     * 当产生了哪些异常,就执行当前注解添加的方法
     */
    Class<? extends Throwable>[] value() default {};

}

@ExceptionHandler用于全局处理控制器里的异常

13.@ControllerAdvice、@RestControllerAdvice

@Target(ElementType.TYPE) // 该注解是添加在类上的
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice {

    /**
     * 指定包下的控制器(Controller)
     */
    @AliasFor("basePackages")
    String[] value() default {};
    @AliasFor("value")
    String[] basePackages() default {};

    /**
     * 指定类所在的包和子包里面的控制器(Controller)
     */
    Class<?>[] basePackageClasses() default {};

    /**
     * 直接给定控制器对应的class
     */
    Class<?>[] assignableTypes() default {};

    /**
     * 添加了指定注解的控制器(Controller)
     */
    Class<? extends Annotation>[] annotations() default {};

}

@ControllerAdvice(@RestControllerAdvice),Controller增强器。可以将对于控制器的全局配置(@ExceptionHandler、@InitBinder、@ModelAttribute)放在同一个位置(放到添加了@ControllerAdvice类中去实现)。所有有@ControllerAdvice出现的地方的类的方法里面肯定被@ExceptionHandler、@InitBinder、@ModelAttribute当中的一个修饰。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!