SpringMVC_02_请求参数的绑定、常见的注解

第三章 请求参数的绑定

3.1 请求参数的绑定说明

  • 我们都知道,表单中请求参数都是基于 key=value 的。
  • SpringMVC 绑定请求参数的过程是通过把表单提交请求参数,作为控制器中方法参数(形参) 进行绑定的
  • SpringMVC 绑定请求参数是自动实现的,但是要想使用,必须遵循使用要求
  • 支持的数据类型:
    • 基本数据类型和字符串类型
    • 实体类型(如:JavaBean)POJO 类型参数
    • 集合数据类型(List、map集合等)

3.2 基本数据类型和字符串类型的绑定

  • 要求: 请求消息中的的参数名控制器中方法参数(形参)名 相同,就会进行对应赋值

  • 注意: 区分大小写

  • <a href="paramController/textParam1?name=zhangsan&age=20">基本请求参数的绑定</a>
    
  • //基本请求参数的绑定
    @RequestMapping("/textParam1")
    public String textParam1(String name,int age){
       System.out.println("name:"+name);
       System.out.println("基本请求参数的绑定");
       return "success";
    }
    

3.3 实体类型(JavaBean)的绑定

  • 其实就是以PoJo类型方式进行赋值

  • 请求参数 和 JavaBean中的属性名称 相同 ,该参数被封装到JavaBean对象中

  • 如果 JavaBean类中包含其他的引用类型,那么 请求参数需要编写成:属性对象.属性,以点的方式赋值

  • public class Account implements Serializable {
           private String username;
           private String password;
           private Double money;
        	//该对象里面还有自定义的对象
           private User user;
        //get和set、toStirng方法省略
       }
    ------------------------------------------------------------------------------------
     public class User {
    	private String username;
    	private String age;
     }
    
  • <%--javaBean请求参数的绑定--%>
    <form action="paramController/textAccountBean" method="post">
        <h2>请求参数的绑定</h2>
        <%--直接写JavaBean对象中的属性名,如果为自定义对象,通过点的方式--%>
        <!-- 给account中的username属性赋值 -->
        姓名:<input type="text" name="username" /><br/>
        密码:<input type="text" name="password" /><br/>
        金额:<input type="text" name="money" /><br/>
         <!-- 给account中的user对象属性的uaername属性赋值 -->
        用户名:<input type="text" name="user.username" /><br/>
        用户年龄:<input type="text" name="user.age" /><br/>
        <input type="submit" value="提交" />
    </form>
    
  • @RequestMapping("/textAccountBean")
    public String textAccountBean(Account account){
       System.out.println("account:"+account.toString());
       System.out.println("JavaBean请求参数的绑定");
       return "success";
    }
    

3.4 给集合属性数据封装

  • list类型的数据的请求参数: list [i] . 属性

  • map类型集合的请求参数: map['key'].属性

  • 案例:

    • ​ 把数据封装带AccountUsers类中的list和map集合中

      public class AccountUsers {
         private String username;
         private String password;
         private Double money;
         //list类型
         private List<User> list;
         //map类型
         private Map<String,User> map;
          
        	 //get、set等方法省略
      }
      
    • jsp页面的请求参数怎么写

      <%--javaBean请求参数的绑定--%>
      <form action="paramController/textAccountBean" method="post">
          <h2>集合类型请求参数的绑定</h2>
          姓名:<input type="text" name="username" /><br/>
          密码:<input type="text" name="password" /><br/>
          金额:<input type="text" name="money" /><br/>
          <%--AccountUsers对象的list集合--%>
          list[0]用户名:<input type="text" name="list[0].username" /><br/>
          list[0]用户年龄:<input type="text" name="list[0].age" /><br/>
      
          list[1]用户名:<input type="text" name="list[1].username" /><br/>
          list[1]用户年龄:<input type="text" name="list[1].age" /><br/>
          <%--AccountUsers对象的map集合--%>
          map['one']用户名:<input type="text" name="map['one'].username" /><br/>
          map['one']用户年龄:<input type="text" name="map['one'].age" /><br/>
      
          map['two']用户名:<input type="text" name="map['two'].username" /><br/>
          map['two']用户年龄:<input type="text" name="map['two'].age" /><br/>
      
          <input type="submit" value="提交" />
      </form>
      
    • 处理器方法

      //集合类型请求参数的绑定
      @RequestMapping("/textCollection")
      public String textCollection(AccountUsers accountUsers){
         System.out.println("account:"+accountUsers.toString());
         System.out.println("JavaBean请求参数的绑定");
         return "success";
      }
      

3.5 处理请求参数中乱码问题

get请求方式不会出现中文乱码问题,post方式会出现中文乱码问题

  • 方法一:使用request的方法设置

  • 方法二:(推荐)添加SpringMVC提供的解决乱码的过滤器

    • 步骤:

      • web.xml中配置过滤器

      • SpringMVC提供的解决乱码的过滤器:CharacterEncodingFilter

      • 进行参数的初始化的配置

      • <!--配置解决Post中文乱码的过滤器-->
            <filter>
                <filter-name>characterEncodingFilter</filter-name>
                <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
                <!--初始化参数-->
                <init-param>
                    <param-name>encoding</param-name>
                    <param-value>UTF-8</param-value>
                </init-param>
            </filter>
        
            <filter-mapping>
                <filter-name>characterEncodingFilter</filter-name>
                <!--拦截的路径-->
                <url-pattern>/*</url-pattern>
            </filter-mapping>
        

3.6 自定义类型转换器

  • 表单提交的任何数据类型全部都是字符串类型,但是后台定义Integer类型,数据也可以封装上,为什么??
    • 说明Spring框架内部会默认进行数据类型转换。
    • 可以发现在SpringMVC有很多已经帮我们定义好的类型转化类:StringToInteger、StringToBoolean等等
  • (重点)如何自定义数据类型转化???
    1. 创建 自定义类型转化类创建转化器(实现Converter<S, T>接口
    2. 配置自定义类型转换器,在springmvc.xml配置文件中编写配置(把自定义的转化器,放到转化工厂中)
  • 案例:
    • 要求:Date日期的格式都改为 yyyy-MM-dd

      • 第一步: 创建转化器(类)

        public class MyStringToDate implements Converter<String, Date> {
        
           public Date convert(String s) {
        
              if (s==null){
                 throw  new RuntimeException("参数有误");
              }
              DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
              try {
                 //字符串转化为指定格式的日期
                 return  df.parse(s);
              } catch (Exception e) {
                 e.printStackTrace();
                 throw new RuntimeException("类型转化出现错误");
              }
           }
        }
        
      • 第二步:配置类型转换器(在SpringMVC中配置)

      • 类型转化工厂是固定的 ConversionServiceFactoryBean

      • 把刚刚自己自定义的类型转化器,放到该工厂中(一个set集合中)

        <!--配置自定义类型转化器-->
        <!--这个ConversionServiceFactoryBean类是固定的类型转换器工厂-->
        <bean id="conversionServiceFactoryBean" class="org.springframework.context.support.ConversionServiceFactoryBean">
           <!--把自己定义的类型转换器,添加到工厂中-->
            <property name="converters">
                <set>
                    <bean class="com.zy.converter.MyStringToDate"/>
                </set>
            </property>
        </bean>
        
        
        <!--让上面的配置生效-->
        <!--开启SpringMVC注解的支持-->
        <mvc:annotation-driven conversion-service="conversionServiceFactoryBean" />
        

3.7 如何在控制器中使用原生的ServletAPI对象??

  • 什么是ServletAPI?? 就是指request、 response等对象
  • 如何在控制器中拿到Servlet对象??
    • 在控制器方法的形参上 添加ServletAPI的参数,控制器就可以使用该ServletAPI
      • 在控制器的形参中添加:
        • HttpServletRequest request servlet中的request对象
        • HttpServletResponse response servlet中的response对象
        • HttpSession session = request.getSession() session对象
        • ServletContext servletContext = session.getServletContext() context对象
        • Model model 这个参数,可以给我们提供大量的Servlet方法

第四章 常见的注解

1、@RequestParam注解

  • 作用:

    • 请求中指定名称的参数 给 控制器中的形参赋值
    • 解决了控制器形参的名称必须和请求参数名一致的问题(当不一致的时候,可以 添加该注解进行指明)
  • 属性:

    • value 属性:请求参数中的名称
    • required 属性:请求参数中是否必须提供此参数。默认值:true。表示必须提供,如果不提供将报错
  • 案例代码:

    • ​ jsp代码

      <%--@RequestParam注解--%>
      <a href="annoController/testRequestParam?username=zhangsan">@RequestParam注解</a>
      
    • //@RequestParam注解
      @RequestMapping("/testRequestParam")
      public String testRequestParam(@RequestParam(value = "username") String name){
         System.out.println(name);
         return "success";
      }
      

2、@RequestBody注解

  • 作用:

    • 用于获取请求体的内容,传入控制器方法参数
    • (注意:get方法不可以)get方法没有请求体
    • (超链接的请求方式是get)
  • 属性:

    • required 属性:是否必须有请求体,默认值是true
  • 案例代码:

    • <%--@RequestBody注解--%>
      <%--该地方不能用超链接,超链接是get的请求方式--%>
      <form action="annoController/testRequestBody" method="post">
          用户姓名:<input type="text" name="username"/><br>
          用户年龄:<input type="text" name="age"/><br>
          <input type="submit" value="提交">
      </form>
      
    • //@RequestBody注解
      //会把整个请求体都赋值给body属性
      @RequestMapping("/testRequestBody")
      public String testRequestBody(@RequestBody String body){
         System.out.println(body);
         return "success";
      }
      

3、@PathVariable注解

  • 作用:

    • 拥有绑定url中的占位符的。(把哪个占位符的值,赋值给控制器的哪个参数
    • 例如:url中有 /delete/{id},{id}就是占位符
    • url 支持占位符是 spring3.0 之后加入的。是 springmvc 支持 rest 风格 URL 的一个重要标志
  • Restful风格的URL:

    • 是一种代码的风格
    • 当有多个相同的路径的时候,会根据每个控制器的不同请求方式进行选着具体哪一个控制器的方法
  • 属性:

    • value属性:用于指定 url 中占位符名称。
    • required属性:是否必须提供占位符。
  • 案例代码:

    • <%--@PathVariable--%>
      <a href="annoController/textPathVariable/521">@PathVariable注解</a>
      
    • //@PathVariable注解
      //把占位符中的中,使用@PathVariable注解拿到该值,赋给id参数
      @RequestMapping("/textPathVariable/{uid}")
      public String textPathVariable(@PathVariable(name="uid") String id){
         System.out.println();
         return "success";
      }
      

4、更改请求方式的过滤器

  • 介绍:
    • 浏览器 form 表单只支持 GET 与 POST 请求
    • 浏览器的a超链接,是发送的GET请求
    • 可以通过 springMVC提供的过滤器,来更改请求方式
    • 可以在浏览器上添加一些插件,来更改请求方式
    • 可以使用 Restful风格 的一些类,可以更改请求方式
  • 通过 springMVC提供的过滤器,来更改请求方式的步骤:
    • 第一步:在 web.xml 中配置该过滤器。
    • 第二步:请求方式必须使用 post 请求。
    • 第三步:按照要求提供_method 请求参数,该参数的取值就是我们需要的请求方式。
    • (具体怎么使用,就不详细介绍了)

5、@RequestHeader注解

  • 作用:

    • 获取指定请求头的值,传入控制器方法参数
    • 把指定请求头的值,赋值给参数
  • 属性:

    • value属性:请求头的名称
  • 案例代码:

    • //@RequestHeader注解
      //获取请求头的值
      @RequestMapping("/textRequestHeader")
      public String textRequestHeader(@RequestHeader(value="Accept") String header){
         System.out.println(header);
         return "success";
      }
      
    • <!--@RequestHeader注解 -->
      <a href="annoController/textRequestHeader">@RequestHeader注解</a>
      

6、@CookieValue注解

  • 作用:

    • 用于获取指定cookie的名称的值,传入控制器方法某个参数
  • 属性:

    • value属性:某个cookie的名称
  • 案例代码:

    • //@CookieValue
      @RequestMapping("/textCookieValue")
      public String textCookieValue(@CookieValue(value="JSESSIONID") String cookieValue){
         System.out.println(cookieValue);
         return "success";
      }
      
    • <!--@CookieValue注解 -->
      <a href="annoController/textCookieValue">@CookieValue注解</a>
      

7、@ModelAttribute注解

  • 作用:

    • 可以用于修饰参数和方法
      • 出现在方法上的作用:
        • 会在控制器的方法执行之前,先执行该方法
        • 该方法可以有返回值,可以无返回值
          • 有返回值:可以把增强的数据返回,会被控制器接收
          • 无返回值:可以通过map集合把对象存起来,在控制器上使用该注解在进行取map中的值
      • 出现在参上上的作用:
        • 获取指定数据,给控制器方法的参数赋值
  • 属性:

    • value属性:用于获取数据的 key。key 可以是 POJO 的属性名称,也可以是 map 结构的 key。
  • 经常使用的场景:

    • 在@ModelAttribute方法上对请求参数进行增强,在进行传给控制器
      • 例:当表单提交数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象原来的数据。
  • 案例代码:

    • 需求: 当表单提交数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象原来的数据

      • 使用有返回值的,可以把增强的数据返回,会被控制器接收

      • jsp文件:
        <%--@MondelAttribute注解--%>
        <%--只提交了User中的username,没提交age,在该注解的方法中先补全age属性,在给控制器--%>
        <a href="annoController/textModelAttribute1?username=zhangsan">@MondelAttribute注解</a>
        --------------------------------------------------------------------------------------------------
        //@ModelAttribute注解(有返回值的)
        	@ModelAttribute
        	public User textModelAttribute(String username){
        		System.out.println("会先执行@ModelAttribute注解的方法");
        		User user = new User();
        		user.setUsername(username);
        		user.setAge("20");
            	//这个user会被控制器中的参数接受到
        		return  user;
        	}
        	
        	@RequestMapping(value = "/textModelAttribute1")
        	public String textModelAttribute1(User user){
        		System.out.println("处理器中的方法执行了");
        		System.out.println(user.toString());
        
        		return "success";
        	}
        
      • 使用无返回值的,可以通过map集合把对象存起来,在控制器上使用该注解在进行取map中的值

      • jsp文件:
        <%--@MondelAttribute注解--%>
        <%--只提交了User中的username,没提交age,在该注解的方法中先补全age属性,在给控制器--%>
        <a href="annoController/textModelAttribute1?username=zhangsan">@MondelAttribute注解</a>
        ------------------------------------------------------------------------------------------------------
        //@ModelAttribute注解(无返回值的)
        	@ModelAttribute
        	public void textModelAttribute2(String username, Map<String,User> map){
        		System.out.println("会先执行@ModelAttribute注解的方法");
        		User user = new User();
        		user.setUsername(username);
        		user.setAge("20");
        		//把增强的数据放到map集合中
        		map.put("user",user);
        	}
        
        	@RequestMapping(value = "/textModelAttribute2")
        	//在map集合中取出user给控制器的参数
        	public String textModelAttribute2(@ModelAttribute(value="user") User user){
        		System.out.println("处理器中的方法执行了");
        		System.out.println(user.toString());
        		return "success";
        	}
        

8、@SessionAttributes注解

  • 作用:

    • 用于多次执行控制器方法间的参数共享
    • 放到类上面当使用该类中的控制器方法的时候,都可以使用通过@SessionAttributes注解已经设置好的session
  • 属性:

    • value属性:用于指定存入的属性名称
    • type属性:用于指定存入的数据类型
  • 案例源码:

    • <%--@SessionAttributes注解--%>
      <a href="annoController/save">向session域中保存数据</a>
      <a href="annoController/find">从session中获取值</a>
      <a href="annoController/delete">清除值session中的值</a>
      ------------------------------------------------------------------------------------------------------
      @Controller
      @RequestMapping(path="/user")
      //@SessionAttributes注解
      // 把数据存入到session域对象中
      @SessionAttributes(value= {"username","password","age"},types={String.class,Integer.class}) 
      public class HelloController {
              //向session中存入值
              @RequestMapping(path="/save")
              public String save(Model model) {
                  System.out.println("向session域中保存数据");
                  model.addAttribute("username", "root");
                  model.addAttribute("password", "123");
                  model.addAttribute("age", 20);
                  return "success";
              }
              // 从session中获取值
              @RequestMapping(path="/find")
              public String find(ModelMap modelMap) {
                  System.out.println("从session中获取值");
                  String username = (String) modelMap.get("username");
                  String password = (String) modelMap.get("password");
                  Integer age = (Integer) modelMap.get("age");
                  System.out.println(username + " : "+password +" : "+age);
                  return "success";
              }
              // 清除值
              @RequestMapping(path="/delete")
              public String delete(SessionStatus status) {
                  System.out.println("清除值session中的值");
                  status.setComplete();
                  return "success";
              }
      }
      
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小镇男孩~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值