1.Spring MVC常用注解

1.@Controller

     @Controller用于标记控制层(Controller层)

2.@Service

     @Service用于标记服务层(Service层)

3.@Repository

     @Repository用于标记访问层(DAO层)

4.@Component

     @Component用于标记实体类层(Entity层),使用该注解,相当于将实体类实例化到Spring容器

5.@RequestMapping

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

@RequestMapping注解支持的属性
属性 类型 是否必要 说明
value String[ ] 用于将指定请求的实际地址映射到方法上(默认属性)
name String 给映射地址指定一个别名(就是一个所谓的类注释,和注释没啥区别,显得更加友好罢了)
method RequestMethod[ ] 映射指定请求的方法类型,常用的是GET,POST
consumes String[ ] 指定处理请求的提交内容类型(Content-Type),例如:application/json、text/html等
produces String[ ] 指定返回的内容类型,返回的内容类型必须是request请求头(Accept)中所包含的类型
params String[ ] 指定请求中,必须包含某些参数值时,才让该方法处理
headers String[ ] 指定请求中必须包含某些指定的header值,才能让该请求方法处理
path String[ ] 和value属性差不多,都是用来作为映射使用的

详细使用,请查看博文:@RequestMapping各个属性的使用https://blog.csdn.net/lzb348110175/article/details/88552507

6.@ResponseBody

@responseBody注解的作用是将Controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到Response对象的body区,通常用来返回JSON数据或者是XML数据。

       需要注意的呢,在使用此注解之后不会再走视图处理器,而是直接将数据写入到输入流中,它的效果等同于通过response对象输出指定格式的数据。

7.@RequestParam

    @RequestParam注解,用于将指定的请求参数赋值给方法中的形参

@RequestParam注解支持的属性
属性 类型 是否必要 说明
value String 指定请求头绑定的名称(默认属性)
name String value属性的别名
required boolean 指定参数是否必须绑定(默认为true)
defaultValue String 如果没有传递参数,则是用默认值
@RequestMapping("test")
public void test(@RequestParam String id,@RequestParam String name){
    System.out.println(id);
    System.out.println(name);
}

①@RequestParam,源码中name的别名是value,value的别名是name。所以说name和value两个属性基本是等价的

②由于value属性是@RequestParam注解的默认属性,因此如果只有唯一的属性,则可以省略该属性名,如果有超过一个属性,则必须写上value属性名称,如下两种是一样子的【@RequestParam(value="id"),@RequestParam("id")】

前端发送请求http://localhost:8080/xxx/test?id=1&name=lzb

第一种情况:
public void test(@RequestParam String id,@RequestParam String name){
    //默认情况,即请求参数和形参进行匹配。此处id,即为请求传过来的id参数,name也一样
    System.out.println(id); ---->1
    System.out.println(name);--->lzb
}

第二种情况:
public void test(@RequestParam("id") String id,@RequestParam("name") String name){
    //由于value属性是@RequestParam注解的默认属性,因此如果只有唯一的属性,则可以省略该属性名,如果有超过一个属性,则必须写上value属性名称,如下两种是一样子的
    //@RequestParam(value="id")
    //@RequestParam("id")
    System.out.println(id); ---->lzb
    System.out.println(name);--->1
}

第三种情况:
public void test(@RequestParam(name="name") String id,@RequestParam(name="id") String name){
    //此处形参id,指定接受的是请求传过来的name属性,形参name,指定接收的是请求传过来的id属性
    System.out.println(id); ---->lzb
    System.out.println(name);--->1
}

第四种情况:
public void test(@RequestParam(defaultValue="88") String id,@RequestParam(defaultValue="Mary") String name){
    //设置默认参数后,请求连接不带参数的话,则形参为默认参数
    System.out.println(id); ---->88
    System.out.println(name);--->Mary
}

第五种情况:
public void test(@RequestParam(required=false) String id,@RequestParam(defaultValue="Mary") String name){
    //设置required=false后,则说明id参数不是必须绑定,发送http://localhost/test请求后,id值就是null了
    System.out.println(id); ---->null
    System.out.println(name);--->Mary
}

8.@PathVariable

     @PathVariable注解,可以非常方便的获取请求URL参数中的动态参数,然后直接赋值给请求方法的形参

@RequestMapping("test/{userId}")
public void test(@PathVariable String userId){
    System.out.println(userId);
}

发送请求URL:http://localhost:8080/test/1001,由@PathVariable 注解的String userId参数会自动获取到URL参数中的动态参数1001,并赋值给形参userId,此处userId即为1001

@RequestMapping("test/{id}")
public void test(@PathVariable(value = "id") String userId){
    System.out.println(userId);
}

如果形参名称和@RequestMapping请求的动态参数名称不一样,则@PathVariable需要加上value属性来设置。从而保证动态参数能够顺利赋值给形参userId

9.@CookieValue

     @CookieValue注解,能够将请求的Cookie数据映射到请求处理方法的形参上

@RequestMapping("test")
public void test(@CookieValue String JSESSIONID){
    System.out.println(JSESSIONID);
}

如果要先在此处获取到JSESSIONID,前提是得在调用该请求之前,设置name为JSESSIONID的cookie信息。然后调用该请求的时候,形参JSESSIONID就能够获取到该Cookie值

@RequestMapping("test")
public void test(@CookieValue(value = "JSESSIONID") String cookie){
    System.out.println(cookie);
}

如果Cookie值的name值和形参中的变量不同(假设Cookie中name值为JSESSIONID,形参值为cookie),则需要使用@CookieValue中的value参数了。需要该value的值与cookie的name值一致,形参才能获取到值。如上所示

@CookieValue注解支持的属性
属性 类型 是否必要 说明
value String 指定请求头绑定的名称(默认属性)
name String value属性的别名
required boolean 指定参数是否必须绑定(默认为true)
defaultValue String 如果没有传递参数,则是用默认值

10.@RequestHeader

     @RequestHeader注释,用于将请求的头信息数据,映射到请求方法的形参上

@RequestMapping("test")
public void test(@RequestHeader("User-Agent") String userAgent,@RequestHeader(value = "Accept") String[] accepts){
    System.out.println(userAgent);
    System.out.println(accepts);
}

 @RequestHeader的使用,和@CookieValue的使用都差不多,支持的属性也都一致,故不作详细解释

@RequestHeader注解支持的属性
属性 类型 是否必要 说明
value String 指定请求头绑定的名称(默认属性)
name String value属性的别名
required boolean 指定参数是否必须绑定(默认为true)
defaultValue String 如果没有传递参数,则是用默认值

11.@SessionAttributes

        @SessionAttributes注解,允许我们有选择地指定Model中的哪些属性,需要转存到HttpSession对象当中

@SessionAttributes只能声明在类上,而不能声明在方法上

@SessionAttribures注解支持的属性
属性 类型 是否必要 说明
value String[ ] Model中属性的名称,即存储在HttpSession当中的属性的名称(默认属性)
names String[ ] value属性的别名
types Class<?> [ ] 指定参数的类型

由于value属性是@SessionAttributes注解的默认属性,因此如果只有唯一的属性,则可以省略该属性名,如果有超过一个属性,则必须写上value属性名称,如下两种是一样子的【@SessionAttributes(value={"user","age","address}),@RequestParam({"user","age","address"})】

@Controller
@RequestMapping("user")
@SessionAttributes(value = {"user","age","address"},types = {String.class,Int.class,String.class})
public class UserController {
    @RequestMapping("getUser")
    @ResponseBody
    public ModelAndView getUser(HttpSession session){
        ModelAndView view = new ModelAndView();
        view.setViewName("getUser");
        view.addObject("user","Mary");
        view.addObject("age",19);
        view.addObject("address","北京市");
        String user = (String)session.getAttribute("user");
        System.out.println(user);
        return view;
    }
}

此处,可以看到@SessionAttributes注解同时将getUser( ) 方法中的"user","age","address"三个同时放入到了HttpSession中,所以通过session.getAttribute("user")即可获取到相关的数据

getUser( )方法结束后,会直接跳转到名称为getUser的页面,在此页面也可以直接通过EL表达式来获取到session数据

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
    <title>getUser</title>
</head>
<body>
    ${sessionScope.user}    ----Mary
    ${sessionScope.age}    -----11
    ${sessionScope.address} ----北京市
</body>
</html>

12.@SessionAttribute

@SessionAttribute注解,能够非常方便的将Session数据映射到请求处理方法的形参上

@SessionAttribure注解支持的属性
属性 类型 是否必要 说明
value String Model中属性的名称,即存储在HttpSession当中的属性的名称(默认属性)
names String value属性的别名
required Class<?>  指定参数是否必须绑定(默认为true)
@RequestMapping("test")
@ResponseBody
public void test(@SessionAttribute String user){
    System.out.println(user);
}

形参和session中的name如果一直的话,可以省去value属性。 @SessionAttribute注解,现在就可以在所有的方法中使用了

@RequestMapping("test")
@ResponseBody
public void test(@SessionAttribute(value = "users") String users){
    System.out.println(users);
}

 综合上述,session中存储的时名称为user的Session数据,此处@SessionAttribute绑定的时名称为users,因为users数据为空,此处会直接报错的,如下所示

org.springframework.web.bind.ServletRequestBindingException: Missing session attribute 'users' of type String
	at org.springframework.web.servlet.mvc.method.annotation.SessionAttributeMethodArgumentResolver.handleMissingValue(SessionAttributeMethodArgumentResolver.java:56)
	at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.handleMissingValue(AbstractNamedValueMethodArgumentResolver.java:215)

如果此处添加requires属性为false,说明参数不需要必须绑定,则此处不会出现上面错误

@RequestMapping("test")
@ResponseBody
public void test(@SessionAttribute(value = "users",required = false) String users){
    System.out.println(users);   ----不会报错,此处输出为null
}

 13.@ModelAttribute

          @ModelAttribute注解,会将请求到的参数绑定到相应的Model对象中

第一种

@Controller
public class HelloWorldController {
    //发送请求:http://localhost:8080/helloWorld?abc=111
    // 1.首先先执行firstVist
    @ModelAttribute
    public void firstVisit(@RequestParam String abc, Model model) {//2.赋值给abc后
        model.addAttribute("attributeName", abc);//3.将abc塞入model的attributeName属性中
    }
    // 4.然后执行helloWorld方法
    @RequestMapping(value = "/helloWorld")
    public String helloWorld() {
        return "getUser";  //5.跳转到getUser页面,页面通过EL表达式${attributeName}即可捕获到值为111
    }
}

发送请求URL:http://localhost:8080/helloWorld?abc=111。被@ModelAttribute注解的firstVisit方法,会优于helloWorld先行调用。它会把请求参数首先赋值给由@RequestParam修饰的abc变量,然后执行model.addAttribute()方法,最后再执行helloWorld方法

第二种(@ModelAttribute注释返回指定具体类的方法)

@Controller
public class HelloWorldController {
    //发送请求:http://localhost:8080/helloWorld
    // 1.首先先执行firstVist
    @ModelAttribute
    public UserfirstVist(@RequestParam(required = false,defaultValue = "nihao") String abc, User user) {//2.请求连接无参数abc,所以此处abc获取默认值"nihao"
        user.setUsername(abc);//3.将"nihao"赋值给user对象 
        return user;//4.此处返回User对象
    }

    // 5.然后执行helloWorld方法
    @RequestMapping(value = "/helloWorld")
    public StringhelloWorld() {
        return "getUser";//6.此处直接跳转到页面,因为4中已经返回了User对象,所以在getUser页面中,通过EL表达式${user.username}仍然时可以访问到username属性的
    }
}

 第三种 (@ModelAttribute注释一个方法的参数,获取到由@ModelAttribute注释的firstVisit方法中的对象的值)

@Controller
public class HelloWorldController {
    //发送请求:http://localhost:8080/helloWorld
    // 1.首先先执行firstVist
    @ModelAttribute
    public void firstVist(@RequestParam(required = false,defaultValue = "nihao") String abc, User user) {//2.请求连接无参数abc,所以此处abc获取默认值"nihao"
        user.setUsername(abc);//3.将"nihao"赋值给user对象 
    }

    // 4.然后执行helloWorld方法
    @RequestMapping(value = "/helloWorld")
    public ModelAndView helloWorld(@ModelAttribute User user) {//5.由于之前User对象所在的方法时被@ModelAttribute注解修饰的,所以在此处可以通过@ModelAttribute来获取user对象信息
        ModelAndView view = new ModelAndView("getUser");
        view.addObject("user",user);//6.将user对象的信息set进view视图中去
        return view;//7.跳转到getUser页面,通过EL表达式 ${user.username}即可获得数据"nihao"
    }
}

第四种(由多个@ModelAttribute修饰的方法)

@Controller
public class HelloWorldController {
    //发送请求:http://localhost:8080/helloWorld?abc=111&aaa=北京市
    // 1.首先先执行firstModelttribute
    @ModelAttribute
    public User firstModelttribute(@RequestParam(required = false,defaultValue = "nihao") String abc, User user) {
        user.setUsername(abc);
        return user;
    }
    // 2.再执行secondModelttribute(两个被@ModelAttribute修饰的方法,根据顺序来先后执行,谁在前谁先执行)
    @ModelAttribute
    public User secondModelttribute(@RequestParam(required = false,defaultValue = "wori") String aaa, User user) {
        user.setAddress(aaa);
        return user;
    }

    @RequestMapping(value = "/helloWorld")
    public ModelAndView helloWorld() {
        ModelAndView view = new ModelAndView("getUser");
        return view;
    }
}

第五种(@ModelAttribute和@RequestMapping注释同一个方法)

@Controller
public class HelloWorldController {
    @RequestMapping(value = "/helloWorld")
    @ModelAttribute(value = "username")
    public String helloWorld() {
        return "getUser";
    }
}

发送请求URL:http://localhost:8080/helloWorld

具体步骤:

①@ModelAttribute和@RequestMapping同时注释一个方法,则此时return  "getUser"返回的并不是一个试图名称,而是model属性值,视图名称则时@RequestMapping的value值"/helloWorld"

②发送如上请求,如果helloWorld试图不存在时,直接会报404找不到

③此时,Model的属性名称是由@ModelAttribute中的value值指定。相当于request中封装了username(key)= getUser(value)

④跳转到helloWorld视图。通过EL表达式${username}就可以获取到值,值为getUser

⑤这种情况下,只能返回username一个属性。暂时也不知道如何返回到视图一个User对象,有待研究

 14.@RequestBody(2019.03.22新增)

         @RequestBody注解,会将ajax等请求中传递的Json对象的字符串,直接绑定到相对应的Bean实体类上,也可以将其分别绑定到对应的字符串上。。切记:接收的是一个Json对象的字符串,而不是一个Json对象。

         通过@requestBody可以将请求体中的JSON字符串绑定到相应的bean上,当然,

         然而在ajax请求往往传的都是Json对象,后来发现用 JSON.stringify(data)的方式就能将对象变成字符串。

@requestBody注解常用来处理content-type不是默认的application/x-www-form-urlcoded编码的内容,比如说:application/json或者是application/xml等。一般情况下来说常用其来处理application/json类型

$.ajax({
  url:"/login",
  type:"POST",
  data:'{"userName":"admin","pwd","admin123"}',
  content-type:"application/json",
  success:function(data){
    alert("request success ! ");
  }
});
@requestMapping("/login")
//1.使用@RrequestBody将json数据分别绑定到相对应字符串上
public void login(@RequestBody String userName,@RequestBody String pwd){
  System.out.println(userName+" :"+pwd);
}
//2.使用@RequestBody将json数据绑定到实体类bean上,[实体类Userr如下]
public void login(@RequestBody User user){
  System.out.println(user.userName+" :"+user.pwd);
}

//实体类User

public class User {

    private String userName;
    
    private String pwd;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
}

需要注意的是,JSON字符串中的key必须对应user中的属性名,否则是请求不过去的。

备注:在一些特殊情况@RequestBody也可以用来处理content-type类型为application/x-www-form-urlcoded的内容,只不过这种方式不是很常用,在处理这类请求的时候,@RequestBody会将处理结果放到一个MultiValueMap<String,String>中,这种情况一般在特殊情况下才会使用,
  例如jQuery easyUI的datagrid请求数据的时候需要使用到这种方式、小型项目只创建一个POJO类的话也可以使用这种接受方式

---->如有疑问,请发表评论,或者联系博主:[email protected],欢迎哦^_^

猜你喜欢

转载自blog.csdn.net/lzb348110175/article/details/88549860