Spring MVC 中的常用注解整理

现将 Spring MVC 中常用注解的使用整理如下.


@Controller

@Controller 注解可以标记一个类, 指明该类是一个控制器(Controller).

要想使 Spring 能够识别出使用 @Controller 标记的类使一个控制器, 还需要进行相应的配置, 有两种配置方式:

1、在 Spring MVC 的配置文件中定义一个 MyController(这是我们自定义的控制器,用@Controller标记)bean 对象.

<bean class="com.tao.myapp.web.controller.MyController"/>

2、 在 Spring MVC 的配置文件中开启注解自动扫描, 让 Spring 自动的去指定的包下面扫描 @Controller 注解的类.

<context:component-scan base-package="com.tao.myapp.web.controller"/>

context:component-scan 默认扫描的注解类型是 @Component, 不过, 在 @Component 语义基础上细化后的 @Repository, @Service@Controller 也同样可以被 context:component-scan 扫描识别.


@Component

这个注解是一个通用的注解, 表示 Spring 中的一个组件, 当我们不太清楚一个类要归到哪个层的组件中去的时候,可以使用这个注解, 不过通常 不建议使用.


@Repository

这个注解用于 dao 层, 通常注解到 daoImpl 类上面.


@RequestMapping

这个注解是一个用来处理请求地址映射的注解, 可用于类或方法上. 用于类上, 表示类中的所有响应请求的方法都是以该地址作为父路径; 用于方法上, 表示特定而url请求将会被该方法处理.

@RequestMapping 的属性如下:

1、valuemethod

  • value: 指定请求的 url 路径. 在使用的时候 value 字段可以省略, url 用引号括起来. value 还支持通配符 "*""**".
@Controller  
@RequestMapping("/myapp")  
public class MyController {  

    /** 可以通过 http://localhost:8080/myapp/haha/test 访问 */
    @RequestMapping("*/test")  
    public String test() {  
       System. out .println( "-----myapp test-----" );  
       return "test" ;  
    }  
}  
  • method: 指定请求的 method 类型, GETPOSTPUTDELETE等. 也可以通过 @GetMapping@PostMapping 等注解替换.
    @RequestMapping(value = "/testMethod" , method = {RequestMethod.GET, RequestMethod.DELETE})
    public String testMethod() {  
       return "method";  
    } 

2、consumesproduces

  • consumes: 指定请求的提交的内容的类型( Content-Type ), 例如 application/json, text/html.

  • produces: 指定返回的内容类型, 仅当 request 请求头中的( Accept )类型中包含该指定类型才返回.

3、 paramsheaders

  • params: 指定 request 中必须包含某些参数值时, 才让该方法处理.
    @RequestMapping(value = "/testParams", params = {"param1=value1", "param2", "!param3"})
    public String testParams() {  
       System.out.println("-----------test Params-----------");  
       return "testParams";  
    }  

如上例所示, params 属性指定了三个参数, 这些参数都是针对请求参数而言的, 它们分别表示参数 param1 的值必须等于 value1; 参数 param2 必须存在, 值无所谓; 参数 param3 必须不存在. 只有当请求 /testParams 并且满足指定的三个参数条件的时候才能访问到该方法. 所以当请求 /testParams?param1=value1&param2=value2 的时候能够正确访问到该 testParams() 方法, 当请求 /testParams?param1=value1&param2=value2&param3=value3 的时候就不能够正常的访问到该方法. 因为在 params 参数里面指定了参数 param3 是不能存在的.

  • headers: 指定 request 中必须包含某些指定的 header 值, 才能让该方法处理请求.
    @RequestMapping(value = "/testHeaders" , headers = {"host=localhost" ,"Accept"})
    public String testHeaders() {  
       return "headers";  
    }  

headers 属性的用法和功能与 params 属性相似.

在上面的代码中当请求 /testHeaders 的时候, 只有当请求头包含 Accept 信息, 且请求的 hostlocalhost 的时候才能正确的访问到 testHeaders() 方法.


@Resource@Autowired

@Resource@Autowired 都是做 bean的注入时使用.

@Resource不是 Spring 的注解, 它的包是 javax.annotation.Resource.

两者都可以写在字段和setter方法上. 两者如果都写在字段上, 那么就不需要再写setter方法.

1、 @Autowired

@AutowiredSpring 提供的注解, 所在的包为 org.springframework.beans.factory.annotation.Autowired.

@Autowired 注解是按照类型( byType) 装配依赖对象的, 默认情况下它要求依赖对象必须存在, 如果允许null值, 可以设置它的 required 属性为 false. 如果我们想使用按照名称( byName ) 来装配, 可以结合 @Qualifier 注解一起使用.

2、 @Resource

@Resource 默认按照名称( byName ) 来自动注入. @Resource 有两个重要的属性: nametype. Spring@Resource 注解的 name 属性解析为 bean 的名字, 而 type 属性则解析为 bean 的类型. 所以, 如果使用 name 属性, 则使用 byName 的自动注入策略; 而使用 type 属性时则使用 byType 自动注入策略. 如果既不指定 name 也不指定 type属性, 这时将通过反射机制使用 byName 自动注入策略.

最好是将 @Resource 放在 setter 方法上, 因为这样更符合面向对象的思想, 通过 setget 去操作属性, 而不是直接去操作属性.

@Resource 的作用相当于 @Autowired, 只不过 @Autowired 默认是按照 byType 自动注入.


@PathVariable

这个注解用于将请求 url 中的模板变量映射到处理方法的参数上, 也就是说从请求的路径上取出需要的参数.

    @Controller    
    public class TestController {    

        @RequestMapping(value = "/user/{userId}/roles/{roleId}", method = RequestMethod.GET)
        public String getLogin(
            @PathVariable("userId") String userId, 
            @PathVariable("roleId") String roleId) {

            System.out.println("User Id : " + userId);
            System.out.println("Role Id : " + roleId);
            return "hello";
        }

        @RequestMapping(value = "/javabeat/{regexp1:[a-z-]+}", method = RequestMethod.GET)    
        public String getRegExp(@PathVariable("regexp1") String regexp1) {    

            System.out.println("URI Part 1 : " + regexp1);
            return "hello";
        }    
    }  
    @Controller  
    @RequestMapping("/test/{variable1}")  
    public class MyController {  

        @RequestMapping("/showView/{variable2}")  
        public ModelAndView showView(
            @PathVariable("variable1") String variable1, 
            @PathVariable("variable2") int variable2) {

        ModelAndView modelAndView = new ModelAndView();  
        modelAndView.setViewName("viewName");  
        modelAndView.addObject("需要放到 model 中的属性名称", "对应的属性值,它是一个对象");  
        return modelAndView;  
        }  
    }  

@RequestHeader

这个注解可以将 Request 请求(HTTP请求)中的 header 请求头部分的属性值绑定到处理方法的参数上.

Host                    localhost:8080    
Accept                  text/html,application/xhtml+xml,application/xml;q=0.9    
Accept-Language         fr,en-gb;q=0.7,en;q=0.3    
Accept-Encoding         gzip,deflate    
Accept-Charset          ISO-8859-1,utf-8;q=0.7,*;q=0.7    
Keep-Alive              300    


    @RequestMapping("/displayHeaderInfo")      
    public void displayHeaderInfo(
        @RequestHeader("Accept-Encoding") String encoding, 
        @RequestHeader("Keep-Alive") long keepAlive) {

        System.out.println("Accept-Encoding : " + encoding);
        System.out.println("Keep-Alive : " + keepAlive);
    }    

上面的代码, 通过使用 @RequestHeaderheader 部分的 Accept-Encoding 的值绑定到参数 encoding 上了; 把 Keep-Alive 的值绑定到参数 keepAlive 上了.


@CookieValue

这个注解可以将 Request 请求( HTTP请求 )的 header 头部信息中关于 Cookie 的值绑定到方法的参数上.

假设有如下 Cookie 值:
JSESSIONID=415A4AC178C59DACE0B2C9CA727CDD84

    @RequestMapping("/displayHeaderInfo")
    public void displayHeaderInfo(@CookieValue("JSESSIONID") String cookie) {

        System.out.println("Cookie : " + cookie);
    }

@RequestParam

这个注解主要用于在 Spring MVC 后台控制层获取请求参数.

通常在 Controller 中获取请求参数有两种方法:
1. request.getParameter(“参数名”)
2. 使用 @RequestParam 注解

@RequestParam 有三个常用参数:

value = “isApp”, required = false, defaultValue = “0”

  • value: 参数名字, 即前端传入的请求中参数的名字.
  • required: 是否必须, 默认是true, 表示请求中一定要有相应的参数, 否则将报404错误码.
  • defaultValue: 参数的默认值, 表示如果请求中没有同名参数时的默认值, 默认值可以是SpEL表达式, 如“#{systemProperties['java.vm.version']}”.

假设请求的url为
localhost:8080/myapp/test/?userName=zhangsan

    @GetMapping("/requestParm")
    public void getRequestParm(@RequestParam(value = "username", required = false, defaultValue = "admin") String username) {

        System.out.println("username : " + username);
    }

注意: 如果设置了 defaultValue 的值, 它将默认的设置 required 的值为 false.


@RequestBody

这个注解用于将 Controller 的方法参数, 根据 HTTP Request HeaderContent-Type 的内容, 通过适当的 HttpMessageConverter 转换为 Java 类.

POST 或者 PUT 的数据是 JSON 格式或者 XML 格式, 而不是普通的键值对形式的时候使用这个注解.

    @RequestMapping(value = "/testRequestBody", method = RequestMethod.POST)
    @ResponseBody
    public Person testRequestBody(@RequestBody Person p) {

        System.out.println("creating a person : " + p);
        return p;
    }

对应的前端 ajax 请求:

    $.ajax({
        url: "testRequestBody",
        data: '{"name":"小红","age":12}', //要用双引号!!
        contentType: "application/json;charset=utf-8", // 因为上面是json数据

        type: "POST",
        headers: {
            // Accept: "application/xml",
            Accept: "application/json",
        },
        success: function (data, textStatus) {
            console.log(data);
            alert(data);
        },
        error: function (data, textStatus, errorThrown) {
            console.log(data);
        },
    });

@ResponseBody

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

当返回的数据不是 html 标签的页面, 而是其他某种格式的数据时( 如 jsonxml 等 )使用.


@ExceptionHandler

注解到方法上,出现异常时会执行该方法.


@ControllerAdvice

这个注解能够使一个 Contoller 成为全局的异常处理类, 类中用 @ExceptionHandler 注解的方法可以处理所有 Controller 发生的异常.

    @ControllerAdvice  
    public class GlobalExceptionHandler {

        private final Logger logger = LoggerFactory.getLogger(getClass());  

        @ExceptionHandler(BusinessException.class)
        @ResponseBody
        public ResponseMsg businessError(BusinessException exception) {

            logger.info("Request raised a BusinessException, business code is {}", exception.getCode());
            return new ResponseMsg(exception.getCode(), exception.getMessage());
        }

        @ExceptionHandler(Exception.class)
        @ResponseBody
        public ResponseMsg sysError(Exception exception) {

            String msg = "出错了";
            if(exception instanceof MaxUploadSizeExceededException) {
                msg = "上传文件过大";  
            }
            //exception.printStackTrace();
            logger.error("Request raised " + exception.getClass().getSimpleName(), exception);
            return new ResponseMsg(GeneralConst.SYS_ERROR, msg);
        }
    }  

@InitBinder

使用 @InitBinder 来处理Date类型的参数.

    //the parameter was converted in initBinder
    @RequestMapping("/date")
    public String date(Date date) {
        System.out.println(date);
        return "hello";
    }

    //At the time of initialization,convert the type "String" to type "date"
    @InitBinder
    public void initBinder(ServletRequestDataBinder binder) {
        binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
    }

参考:
https://blog.csdn.net/chenpeng19910926/article/details/70837756

猜你喜欢

转载自blog.csdn.net/hbtj_1216/article/details/80253889