Day_08 SpringMVC

01-请求参数绑定之JavaBean包装类(掌握)

  • JavaBean包装类个实体类

    • 一个实体类中包含另一个实体类
  • 代码实现

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>01-请求参数绑定之JavaBean包装类</title>
    </head>
    <body>
    
    <form th:action="@{/request/test1}">
    
        账户:<input type="text" name="user.userName"><br>
        密码:<input type="text" name="user.userPwd"><br>
        <button type="submit">提交</button>
    
    </form>
    
    </body>
    </html>
    
    @RequestMapping("/demo01.html")
    public ModelAndView toDemo01Page(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("demo01");
        return modelAndView;
    }
    
    @RequestMapping("/request/test1")
    public ModelAndView test1(UserWrapper userWrapper){
        System.out.println("userWrapper = " + userWrapper);
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("index");
        return modelAndView;
    }
    

02-请求参数中文乱码(掌握)

  • 回顾

    • get请求,没有请求参数中文乱码
    • post请求,有请求参数中文乱码
  • 概述

    • SpringMVC内置了CharacterEncodingFilter过滤器,来解决中文乱码问题.
  • 代码实现

    <filter>
        <filter-name>encoding</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>
        <init-param>
            <param-name>forceRequestEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    
  • 补充

    <!--
        path : 访问路径
        view-name : 逻辑视图名称
    -->
    <mvc:view-controller path="/demo01.html" view-name="demo01"></mvc:view-controller>
    <mvc:view-controller path="/demo02.html" view-name="demo02"></mvc:view-controller>
    

03-请求参数绑定之容器(掌握)

  • 代码实现

    @RequestMapping("/request/test3")
    public ModelAndView test3(Integer[] ids){
        System.out.println("ids = " + Arrays.toString(ids));
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("index");
        return modelAndView;
    }
    
    
    @RequestMapping("/request/test4")
    public ModelAndView test4(@RequestParam("ids") List<Integer> ids){
        System.out.println("ids = " + ids);
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("index");
        return modelAndView;
    }
    

04-请求参数绑定练习(掌握)

  • 代码实现

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>04-请求参数绑定练习</title>
    </head>
    <body>
    
    <form th:action="@{/request/test5}" method="post">
    
        学生姓名:<br>
        <input type="text" name="stuName"><br>
        学校名称:<br>
        <input type="text" name="school.schoolName"><br>
        学科一(list):<br>
        <input type="text" name="subjectList[0].subjectName"><br>
        学科二(list):<br>
        <input type="text" name="subjectList[1].subjectName"><br>
        学科三(list):<br>
        <input type="text" name="subjectList[2].subjectName"><br>
        学科一(array):<br>
        <input type="text" name="subjectArr[0].subjectName"><br>
        学科二(array):<br>
        <input type="text" name="subjectArr[1].subjectName"><br>
        学科三(array):<br>
        <input type="text" name="subjectArr[2].subjectName"><br>
        分数一:<br>
        <input type="text" name="scores['javase']"><br>
        分数二:<br>
        <input type="text" name="scores['javame']"><br>
        分数三:<br>
        <input type="text" name="scores['javaee']"><br>
    
        <button type="submit">提交</button>
    
    </form>
    
    
    </body>
    </html>
    
    @RequestMapping("/request/test5")
    public ModelAndView test5(Student student) {
        System.out.println("student = " + student);
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("index");
        return modelAndView;
    
    }
    

05-@RequestHeader注解(掌握)

  • 概述

    • Annotation which indicates that a method parameter should be bound to a web request header.
    • 设置请求头的绑定规则
  • 源码

    @Target(ElementType.PARAMETER)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface RequestHeader {
    
       @AliasFor("name")
       String value() default "";
    
       @AliasFor("value")
       String name() default "";
    
    
       boolean required() default true;
    
    
       String defaultValue() default ValueConstants.DEFAULT_NONE;
    
    }
    
  • 代码实现

    @RequestMapping("/request/test6")
    public ModelAndView test6(@RequestHeader(name = "User-Agent" , required = false,defaultValue = "missing") String myHeader){
        System.out.println("myHeader = " + myHeader);
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("index");
        return modelAndView;
    }
    

06-@CookieValue注解(掌握)

  • 概述

    • Annotation to indicate that a method parameter is bound to an HTTP cookie.
    • 设置Cookie的绑定规则
  • 代码实现

    @RequestMapping("/request/test7")
    public ModelAndView test7(@CookieValue(name = "history", required = true, defaultValue = "missing") String myCookie) {
        System.out.println("myCookie = " + myCookie);
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("index");
        return modelAndView;
    }
    

07-Handler返回ModelAndView(掌握)

  • 概述

    • ModelAndView对象中包含一个model(模型)和一个view(视图)
      • model(模型) : 封装数据,保存在request域
      • view(视图) : 逻辑视图名称,用于做请求转发
  • 代码实现

    @RequestMapping("/response/test1")
    public ModelAndView test1(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("msg","好好学习,天天向上,不要老想着玩.");
        modelAndView.setViewName("response1");
        return modelAndView;
    }
    
    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>07-Handler返回ModelAndView</title>
    </head>
    <body>
    
    <span th:text="${msg}"></span>
    
    </body>
    </html>
    

08-Handler返回字符串(掌握)

  • 概述

    • 返回字符串可以指定逻辑视图的名称,根据视图解析器为物理视图的地址。
  • 代码实现

    @RequestMapping("/response/test2")
    public String test2(Model model){
        model.addAttribute("msg","helloworld");
        return "response2";
    }
    

09-Handler操作转发和重定向(掌握)

  • 概述

    • Handler返回ModelAndView或String都只能转发到ThymeleafViewResolver所指定的目录"/WEB-INF/pages/"下;
    • 如果想要跳转到"/WEB-INF/pages/"目录以外的资源,就需要操作转发和重定向.
  • 代码实现

    //①转发到目录以外的资源
    @RequestMapping("/response/test3")
    public String test3(){
        return "forward:/html/response3.html";
    }
    
    //②转发到指定的处理器
    @RequestMapping("/response/test4")
    public String test4(){
        return "forward:/response/test3";
    }
    
    //③直接调用处理器方法
    @RequestMapping("/response/test5")
    public String test5(){
        return test3();
    }
    
    
    //④重定向到目录以外的资源
    @RequestMapping("/response/test6")
    public String test6(){
        return "redirect:/html/response3.html";
    }
    
    
    //⑤重定向到处理器
    @RequestMapping("/response/test7")
    public String test7(){
        return "redirect:/response/test6";
    }
    
    //⑥直接调用处理器方法
    @RequestMapping("/response/test8")
    public String test8(){
        return test6();
    }
    

10-原生ServletAPI对象概述(掌握)

  • 分类
    • ServletRequest : 请求对象
    • ServletResponse : 响应对象
    • HttpSession : 会话对象
    • ServletContext : 项目上下文对象

11-获取request和response对象(掌握)

  • 代码实现

    @RequestMapping("/servlet/test1")
    public String test1(HttpServletRequest request , HttpServletResponse response){
        System.out.println("request = " + request);
        System.out.println("response = " + response);
        return "index";
    }
    

12-获取session对象(掌握)

  • 代码实现

    @RequestMapping("/servlet/test2")
    public String test2(HttpServletRequest request){
        HttpSession session = request.getSession();
        System.out.println("session = " + session);
        return "index";
    }
    
    @RequestMapping("/servlet/test3")
    public String test3(HttpSession session){
        System.out.println("session = " + session);
        return "index";
    }
    

13-获取ServletContext对象(掌握)

  • 代码实现

    @RequestMapping("/servlet/test4")
    public String test4(HttpServletRequest request){
        ServletContext servletContext = request.getServletContext();
        System.out.println("servletContext = " + servletContext);
        return "index";
    }
    
    @Autowired
    private ServletContext servletContext;
    
    @RequestMapping("/servlet/test5")
    public String test5(){
        System.out.println("servletContext = " + servletContext);
        return "index";
    }
    

14-操作请求域(掌握)

  • 概述

    • 可以通过Model,ModelMap,Map,HttpServletRequest,ModelAndView来操作请求域对象.
  • 继承结构

    • image-20220401142942471
    • Map,ModelMap,Model底层具体由BindingAwareModelMap来实现,都是通过WebEngineContext的setVariable方法来操作请求域对象;
    • ModelAndView包含一个ModelMap对象,由ModelMap对象来操作请求域对象
  • 代码实现

    @RequestMapping("/domain/test1")
    public String test1(Model model){
        model.addAttribute("msg1","hello1");
        return "domain";
    }
    
    @RequestMapping("/domain/test2")
    public String test2(ModelMap modelMap){
        modelMap.addAttribute("msg2","hello2");
        return "domain";
    }
    
    @RequestMapping("/domain/test3")
    public String test3(Map map){
        map.put("msg3","hello3");
        return "domain";
    }
    
    @RequestMapping("/domain/test4")
    public String test4(HttpServletRequest request){
        request.setAttribute("msg4","hello4");
        return "domain";
    }
    
    @RequestMapping("/domain/test5")
    public ModelAndView test5(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("domain");
        modelAndView.addObject("msg5","hello5");
        return modelAndView;
    }
    

15-操作会话域(掌握)

  • 代码实现

    @RequestMapping("/domain/test6")
    public String test6(HttpSession session){
        session.setAttribute("msg6","hello6");
        return "domain";
    }
    

16-操作应用域(掌握)

  • 代码实现

    @Autowired
    private ServletContext servletContext;
    
    @RequestMapping("/domain/test7")
    public String test7(){
        servletContext.setAttribute("msg7","hello7");
        return "domain";
    }
    

17-SpringMVC类型转换(掌握)

  • 概述
    • SpringMVC 将『把请求参数注入到 POJO 对象』这个操作称为『数据绑定』,英文单词是 binding。数据类型的转换和格式化就发生在数据绑定的过程中。
  • 分类
    • 自动类型转换
      • HTTP 协议是一个无类型的协议,我们在服务器端接收到请求参数等形式的数据时,本质上都是字符 串类型。
      • 而我们在实体类当中需要的类型是非常丰富的。对此,SpringMVC 对基本数据类型提供了自动的类 型转换。
    • 手动类型转换
      • 很多带格式的数据必须明确指定格式之后才可以进行类型转换。最典型的就是日期类型

18-日期类型格式转换(掌握)

  • 概述

    • image-20220401151541496
    • SpringMVC有内置类型格式转换器,默认的格式是"yyyy/MM/dd",所以"2020/02/02"是可以请求参数绑定成功,而"2020-02-02"请求参数绑定失败.
    • 如果想要让"2020-02-02"请求参数绑定成功,就需要修改内置类型格式转换器的格式.
  • 代码实现1

    public class User {
    
        private Integer userId;
        private String userName;
        private String userPwd;
        private Date birthday;
    
    }
    
    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>18-日期类型格式转换</title>
    </head>
    <body>
    
    <form th:action="@{/conversion/test1}">
    
        生日:<input type="text" name="birthday"><br>
        <button type="submit">提交</button>
    
    </form>
    
    
    </body>
    </html>
    
    <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
    
    <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="formatters">
            <set>
                <bean class="org.springframework.format.datetime.DateFormatter">
                    <property name="pattern" value="yyyy-MM-dd"></property>
                </bean>
            </set>
        </property>
    </bean>
    
    @RequestMapping("/conversion/test1")
    public String test1(Date birthday){
        System.out.println("birthday = " + birthday);
        return "index";
    }
    
  • 代码实现2(推荐)

    public class User {
    
        private Integer userId;
        private String userName;
        private String userPwd;
    
        @DateTimeFormat(pattern = "yyyy-MM-dd")
        private Date birthday;
    
    }
    

19-类型转换引入BindingResult接口(掌握)

  • 概述

    • image-20220401153306372
    • 如果格式错误会跳转到400错误页面,该页面的体验极其差.
    • 应该跳转到一个自定义的错误页面,并且展示自定义错误信息.
    • BindingResult接口中包含有错误信息,可以通过它将错误信息取出,并展示到页面上.
  • 代码实现

    @RequestMapping("/conversion/test2")
    public String test2(User user, BindingResult result, Model model) {
    
        if (result.hasErrors()) {
            //你错了没?
            FieldError fieldError = result.getFieldError("birthday");
            System.out.println("fieldError = " + fieldError);
            String errorMsg = fieldError.getDefaultMessage();
            model.addAttribute("errorMsg", "日期格式错误!!");
            return "error";
        }
    
        System.out.println("user = " + user);
        return "index";
    }
    
  • 注意事项

    • IllegalStateException: An Errors/BindingResult argument is expected to be declared immediately after the model attribute
    • BindingResult必须要放在Model实体类后面.

20-自定义类型转换器(了解)

  • 开发步骤

    • ①自定义Converter类实现Converter接口
    • ②编写spring-mvc.xml
      • 配置自定义Converter类
  • ①自定义Converter类实现Converter接口

    public class MyDateConverter implements Converter<String, Date> {
        @Override
        public Date convert(String source) {
            //日期字符串 -> 日期对象
            try {
                return new SimpleDateFormat("yyyy-MM-dd").parse(source);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    
  • ②编写spring-mvc.xml

    <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
    <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="com.atguigu.Converter.MyDateConverter"></bean>
            </set>
        </property>
    </bean>
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值