程序猿阵线联盟-汇总各类技术干货

SpringMVC学习笔记2(注解)

2019-04-23  本文已影响2人  页川叶川

第二部分 注解

1.@Controller:

@Controller 用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller 对象。分发处理器将会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping 注解。
但是单单使用@Controller 标记在一个类上还不能真正意义上的说它就SpringMVC 的一个控制器类,因为这个时候Spring 还不认识它。

这个时候有两种方式可以把MyController 交给Spring 管理,好让它能够识别我们标记的@Controller 。
第一种方式是在SpringMVC 的配置文件中定义MyController 的bean 对象。

<bean class="com.host.app.web.controller.MyController"/>

第二种方式是在SpringMVC 的配置文件中告诉Spring 该到哪里去找标记为@Controller 的Controller 控制器。

< context:component-scan base-package = "com.host.app.web.controller" >
       < context:exclude-filter type = "annotation" expression = "org.springframework.stereotype.Service" />
</ context:component-scan > 

2.@RequestMapping

映射请求参数、请求方法或请求头
映射请求参数、请求方法或请求头.png
@RequestMapping(value="/testMethod",method = RequestMethod.POST)
    public String testMethod() {
        System.out.println("testMethod");
        return SUCCESS;
    }

    /*
    * 了解:可以使用 params 和 headers 来更加精确的映射请求。params 和 headers 支持简单的表达式
    * */
    @RequestMapping(value="/testParamsAndHeader",params = {"username","age!=10"},headers = {})
    public String testParamsAndHeader() {
        System.out.println("testParamsAndHeader");
        return SUCCESS;
    }
@RequestMapping还支持Ant格式通配符
Ant格式通配符.png

3.PathVariable

映射URL绑定的占位符


映射URL绑定的占位符.png
@PathVariable 用例:
    /*
    * @PathVariable 可以来映射URL中的占位符到目标方法的参数中
    * @param id
    * */
    @RequestMapping("/testPathVariable")
    public String testPathVariable(@PathVariable("id") Integer id) {
        System.out.println("testPathVariable: " + id);
        return SUCCESS;
    }

4.@RequestParam

使用@RequestParam绑定请求参数。

  • 在处理方法入参处使用@RequestParam可以把请求参数传递给请求方法
    -value:参数名
    -required:是否必须。默认为true,表示请求参数中必须包含对应的参数,若不存在,将抛出异常
测试用例:
SpringMVCTest.java中添加。
/*
    * @RequestParam
    * -value:参值即请求参数的数名
    * -required:是否必须。默认为true,表示请求参数中必须包含对应的参数,若不存在,将抛出异常
    * -defaultValue:请求参数的默认值
    * */
    @RequestMapping(value = "/testRequestParam")
    public String testRequestParam(@RequestParam(value = "username") String username,
                                   // 此处 age 如果是 int 型变量,就必须设置 defaultValue="0"
                                   @RequestParam(value = "age",required = false) Integer age) {
        System.out.println("testRequestParam,uaername: " + username + " age:" + age);
        return SUCCESS;
    }
-----------------------------------------------------------------
index.jsp:
<a href="springmvc/testRequestParam?username=myName&age=19">Test Rest GET</a><br>

5.@RequestHeader

绑定请求头的属性值

  • 请求头包含了若干个属性,服务器可根据此获知客户端的信息,通过@RequestHeader即可将请求头中的属性值绑定到处理方法的入参中
用例:
/*
    * 映射请求头信息
    * 用法同@RequestParam
    * */
    @RequestMapping(value = "/testRequestHeader")
    public String testRequestHeader(@RequestHeader(value = "User-Agent") String ua) {
        System.out.println("testRequestHeader,User-Agent: " + ua);
        return SUCCESS;
    }
------------------------------------------------------------------
index.jsp:
<a href="springmvc/testRequestHeader">testRequestHeader</a><br>

6.@SessionAttributes

如果希望在多个请求之间共享某个模型属性数据(学习笔记3中会讲到),则可以在控制类上标注一个@SessionAttributes,SpringMVC将在模型中对应的属性暂存到HttpSession中

HttpSession.png

示例:

SpringMVCTest.java 添加:

注意(***): 在 SpringMVCTest 类的上面添加:
           @SessionAttributes(value = {"user"},types = {String.class})

/*
    * @SessionAttributes除了可以通过属性名指定需要放到会话中的属性外(实际上使用的是 value 属性值),
    *                   还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中(实际上使用的是 types 属性值)
    * 注意:该注解只能使用在类的上面,为不能修饰方法
    * */
    @RequestMapping("/testSessionAttributes")
    public String testSessionAttributes(Map<String,Object> map) {
        User user = new User("Tom","123456","tom@qq.com",15);
        map.put("user",user);
        map.put("school","xztywss");
        return SUCCESS;
    }
index.jsp添加:
<a href="springmvc/testSessionAttributes">Test SessionAttributes</a><br>

success.jsp添加:

    request user: ${requestScope.user }  <br><br>

    session user: ${sessionScope.user }  <br><br>

    request school: ${requestScope.school }  <br><br>

    session school: ${sessionScope.school }  <br><br>

7.ModelAttribute

User.java添加属性(getter、setter、toString相应的改变(此处改变后不包括Address属性)):
private Integer id;    

注意:请添加一个不包含Address但是包含id的构造方法,同时应该有一个空的构造方法,不然有可能会出错。

SpringMVCTest.java添加:
/*
    * 有 @ModelAttribute 标记的方法会在每个目标方法被调用之前被 SpringMVC 调用!
    * */
    @ModelAttribute
    public void getUser(@RequestParam(value = "id",required = false) Integer id,
                        Map<String,Object> map) {
        if(id != null) {
            //模拟从数据库中获取对象
            User user = new User(1,"Tom","123456","tom@qq.com",12);
            System.out.println("从数据库中获取一个对象: " + user);

            map.put("user",user);
        }
    }

    @RequestMapping(value = "/testModelAttribute")
    public String testModelAttribute(User user) {
        System.out.println("修改: " + user);
        return SUCCESS;
    }
index.jsp 添加:
<!--
      模拟修改操作
      1.原始数据:1,Tome,123456,tom@qq.com,12
      2.密码不能被修改
      3.表单回显,模拟操作直接在表单填写对应的属性值
   -->
  <form action="springmvc/testModelAttribute" method="post">
      <input type="hidden" name="id" value="1">

      username: <input type="text" name="username" value="Tom"/>
      <br>
      email: <input type="text" name="email" value="tom@qq.com"/>
      <br>
      age: <input type="text" name="age" value="12"/>
      <br>
      <input type="submit" value="Submit">
  </form>
不包含@ModelAttribute注解的getUser()方法时的运行结果:
修改: User{id=1, username='Tom', password='null', email='tom@qq.com', age=123}

包含@ModelAttribute注解的getUser()方法时的运行结果:
从数据库中获取一个对象: User{id=1, username='Tom', password='123456', email='tom@qq.com', age=12}
修改: User{id=1, username='Tom', password='123456', email='tom@qq.com', age=13}

注:主要区别在于password回显上的区别
/*
    * 运行流程:
    * 1.执行 @ModelAttribute 注释修饰的方法:从数据库中取出对象,把对象放入 Map 中。键为:user
    * 2.SpringMVC 从 Map 中取出 User 对象,并把表单的请求参数赋给 User 对象的对应属性。
    * 3.SpringMVC 把上述对象传入目标方法的参数
    *
    * 注意:在 @ModelAttribute 修饰的方法中,放入到 Map 时的键需要和目标方法入参类型的第一个字母小写的字符串一致
    * */
SpringMVC 确定目标方法 POJO 对象类型入参的过程 
1.确定一个 key:
    1).若目标方法的 POJO 类型的参数没有使用@ModelAttribute 作为修饰,则 key 为 POJO 类名的第一个字母小写
    2).若使用了 @ModelAttribute 注解,则 key 为 @ModelAttribute 注解的 value 值
2.在 implicitModel 中查找 key 对应的对象,若存在,则作为入参传入
    1).若在 @ModelAttribute 标记的方法中在 Map 中保存过,且 key 和 1 确定的 key 一致,则会获取到
3.若 implicitModel  中不存在 key 对应的对象,则检查当前 Handler 是否使用 @SessionAttributes 注解修饰,
若使用了该注解,且 @SessionAttributes 注解的 value 属性值中包含了 key,则会从 HttpSession中获取 key 所
对应的 value值,若存在则直接传入到目标方法的入参中。若不存在则抛出异常。
4.若 Handler 没有标识 @SessionAttributes 注解或 @SessionAttributes 注解的 value 值中不包含 key ,则会
通过反射来创建 POJO 类型的参数,传入为目标方法的参数
5.SpringMVC 会把 key 和 POJO类型的对象保存到 implicitModel 中,进而会保存到 request 中。

上一篇下一篇

猜你喜欢

热点阅读