SpringMVC之常用注解

SpringMVC之常用注解

Scroll Down

前言

Spring MVC中用于参数绑定的注解有很多,都在org.springframework.web.bind.annotation包中,根据它们处理的request的不同内容可以分为四类(常用的类型)。
第一类:处理request body部分的注解有:@RequestParam和@RequestBody
第二类:处理requet uri部分的注解有:@PathVaribale
第三类:处理request header部分的注解有:@RequestHeader和@CookieValue
第四类:处理attribute类型的注解有:@SessionAttributes和@MoelAttribute

1.RequestParam

作用:把请求中指定名称的参数给控制器中的形参赋值

属性:

我们可以看一下@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;

}

可以发现源码中有四个属性:
value:请求参数中的名称
name: 跟value一个意思
required: 请求参数中书否必须提供此参数:默认值:true。表示必须提供,如果不提供将报错
defaultValue:在未提供请求参数或请求参数为空值时用作回退的默认值

使用示例:

比如前台传来一个username,后台如果想要接收到username,必须在controller层方法上加一个同名的形参,如果要username和形参名称不相同,可以用RequestParam注解来实现

@Controller
@RequestMapping("/anno")
public class AnnoController {
    @RequestMapping("/testRequestParam")
    public String testRequestParam(@RequestParam(name = "name") String username){
        System.out.println("执行了"+username);
        return "success";
    }
}

前台传入一个name,而形参是username,这时候只需要在形参前面加@RequestParam(name/value="name")即可封装。

2. RequestBody

作用:

此注解在异步时会有作用
用于获取请求体的内容,直接使用得到的是key=value&key=value结构的数据。
get请求方式不适用(没有请求体)

属性:

required:是否必须有请求体,默认是true;当曲志伟true时,get请求会报错,如果取值为法false,get请求得到的是null

使用示例:

    <form action="anno/testRequestBody" method="post">
        用户姓名:<input type="text" name="username" /><br/>
        用户年龄:<input type="text" name="age" /><br/>
        <input type="submit" value="提交" /><br/>
    </form>
    @RequestMapping("/testRequestBody")
    public String testRequestBody(@RequestBody String body){
        System.out.println("执行了"+body);
        return "success";
    }

前台发送表单数据username和age,后台如果要拿到表单请求,在一个形参前面加@RequestBody()注解,就会把表单提交的数据以key=value&key=value的形式保存在形参中

3. PathVariable

前言:关于rest风格

用原来的方式编程,例如:一个controller类写多个方法,每个方法都有一个requestMapping映射路径,根据指定的路径来调用指定方法;
而restful方式是多个方法的请求路径都是相同的,而根据请求方式post/get/put ..来判断选择哪个指定方法执行,但是这就又引出另一个问题,如果请求方式也相同呢?比如要查询指定id的用户和查询所有用户,请求路径和请求方式都是相同的,对于查询指定id的方法,可以在请求路径后加一个占位符
,方法上加形参,就可以区分出来两个方法。
由于rest风格的请求路径都是相同的,所以缓存会存入相同的位置,便于管理
rest风格的优点
1. 结构清晰
2. 符合标准
3. 易于理解
4. 扩展方便

作用:

用于绑定URL中的占位符。例如:url中有/delete/,就是占位符
URL支持占位符是spring3.0之后加入的。是springmvc支持rest风格URL的一个重要标志

属性:

value/name:用于指定URL中占位符名称
required:是否必须提供占位符

使用示例:

<a href="anno/testRequestBody/testPathVariable/10">testPathVariable</a>
 @RequestMapping("/testPathVariable/{id}")
    public String testPathVariable(@PathVariable(name = "id") String id){
        System.out.println("执行了"+id);
        return "success";
    }

前台传入id为10,后台用占位符加@PathVariable注解加形参接收
注意:注解的name/value值必须要和占位符名一致

4. RequestHeader

作用:

用于获取请求消息头

属性:

value/name:提供消息头名称
required:是否必须有此消息头
注:实际开发中一般不太用

5. CookieValue

作用:

用于把指定cookie名称的值传入控制器方法参数

属性:

value/name:指定cookie的名称
required:是否必须有此cookie

使用示例:

<a href="anno/testCookieValue">testCookieValue</a>
@RequestMapping("/testCookieValue")
    public String testCookieValue(@CookieValue(value = "JSESSIONID") String cookie){
        System.out.println("执行了"+cookie);
        return "success";
    }

6. ModelAttribute

作用:

该注解是SpringMVC4.3版本之后新加入的,它可以用于修饰方法和参数。
出现在方法上,表示当前方法会在控制器的方法执行之前,先执行。它可以修饰没有返回值的方法,也可以修饰具有返回值的方法。
出现在参数上,获取指定的数据给参数赋值

属性:

value/name:用于获取数据的key,key可以使POJO的属性名称,也可以是map结构的key

应用场景:

当表单提交数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象原来的数据。
例如:我们在编辑一个用户时,用户有一个创建信息字段,该字段的值是不允许被修改的。在提交表单数据时肯定没有此字段的内容,一旦更新会把该字段内容默认设置为null,此时就可以使用此注解来调用自己编写好的方法来加入该字段的值返回给controller方法

使用示例:

 <form action="anno/testModelAttribute" method="post">
        用户姓名:<input type="text" name="uname" /><br/>
        用户年龄:<input type="text" name="age" /><br/>
        <input type="submit" value="提交" /><br/>
  </form>

写一个User类,封装uname,age,Date属性
表单只有uname和age属性的提交
我们以map为例:
1. 有返回值的写法:
先写一个被调用的方法

   @ModelAttribute
    public User showUser(String uname){
        System.out.println("showUser执行了。。");
//        模拟通过数据库查询数据
        User user = new User();
        user.setUname(uname);
        user.setAge(20);
        user.setDate(new Date());
        return user;
    }

controller方法:

  @RequestMapping("/testModelAttribute")
    public String testModelAttibute(User user){
        System.out.println("testModelAttribute执行了"+user );
        return "success";
    }

2. 没有返回值的写法:
被调用的方法:

   @ModelAttribute
    public void showUser(String uname, Map<String,User> map){
        System.out.println("showUser执行了。。");
//        模拟通过数据库查询数据
        User user = new User();
        user.setUname(uname);
        user.setAge(20);
        user.setDate(new Date());
        map.put("abc",user);
    }

controller方法:

  @RequestMapping("/testModelAttribute")
    public String testModelAttibute(@ModelAttribute("abc") User user){
        System.out.println("testModelAttribute执行了"+user );
        return "success";
    }

7. SessionAttributes

作用:

用于多次执行控制器方法间的参数共享
只能作用在类上

属性:

value:用于指定存入的属性名称
type:用于指定存入的数据类型

使用示例:

<a href="anno/testSessionAttribute">testSessionAttribute</a>
<a href="anno/getSessionAttribute">getSessionAttribute</a>
@Controller
@RequestMapping("/anno")
@SessionAttributes(value = {"username","password","age"},types={String.class,Integer.class})//把msg=妹妹存入到session域对中
public class AnnoController {
/**
     * SessionAttribute注解,向session中存入值
     */
    @RequestMapping("/testSessionAttribute")
    public String testSessionAttribute(Model model){
        System.out.println("testSessionAttribute执行了");
        //底层会存储到request域对象中
        model.addAttribute("username","root");
	model.addAttribute("age","11");
	model.addAttribute("password","111");	
        return "success";
    }

    /**
     * 从session域中获取值
     * @param modelMap
     * @return
     */
    @RequestMapping("/getSessionAttribute")
    public String getSessionAttribute(ModelMap modelMap){
        System.out.println("getSessionAttribute执行了");
        //底层会存储到request域对象中
        String username = (String) modelMap.get("username");
	String password = (String) modelMap.get("password");
	String age= (String) modelMap.get("age");	
        System.out.println(username+password+age);
        return "success";
    }

}
//清除值
@RequestMapping("/deleteSessionAttribute")
public String delete(SesssionStatus status){
	status.setComplete();
	return "success";
}