zoukankan      html  css  js  c++  java
  • Spring MVC类型转换器

    类型转换器引入

    为什么页面上输入”12”,可以赋值给Handler方法对应的参数?
    这是因为框架内部帮我们做了类型转换的工作。将String转换成int
     但默认类型转换器并不是可以将用户提交的String,转换为用户需要的所有类型。此时 ,就需要自定义类型转换器了

    案例:自定义日期类型转换器

    要求日期格式为:yyyy/MM/dd

     ---单日期(在Controller定义了一个方法,主要是对参数有要求)

    MyCOntroller.java

    package cn.controller;
    
    import java.util.Date;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    /**
     * 
     * @author 景佩佩
     *
     */
    @Controller
    public class MyController{
       //处理器方法
        @RequestMapping(value="/first.do")
        public String doFirst(Date birthday,int age) {
            System.out.println(birthday+"===========");
            System.out.println(age+"===========");
            return "/welcome.jsp";
        }
        
        
    }

    index.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        <style type="text/css">
           form{
            background-color:pink;
             width:500px;
            
           }
        </style>
        <title></title>
      </head>
      
      <body>
      
        <form action="${pageContext.request.contextPath }/first.do" method="post">
        <h1>自定义类型转换器</h1>
                     出生日期:<input name="birthday"/><br/><br/>
                     年龄:<input name="age"/><br/><br/>
           <input type="submit" value="注册"/>
        </form>
      </body>
    </html>

    welcome.jsp(欢迎页面)

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>欢迎页面</title>
      
      </head>
      
      <body>
         <h1>欢迎访问${uname }${param.uage }</h1>
      </body>
    </html>

    定义自己的类型转换器  继承一个父接口 Converter<S, T>

    package cn.converters;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import org.springframework.core.convert.converter.Converter;
    /**
     * 
     * @author 景佩佩
     *
     *S:Source 源类型
     *T:Target 目标类型
     */
    public class MyDateConverter implements Converter<String, Date> {
    
        public Date convert(String source) {
            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
            return null;
        }
    
    }

    applicationContext.xml

    如果换成yyyy-MM-dd格式的

    在applicationContext.xml中


     多种日期格式
    上述页面和applicationContext.xml配置的都一样

     MyController.java中也是一样

    只需在在类型转换器中改一下

    package cn.converters;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.regex.Pattern;
    
    import org.springframework.beans.TypeMismatchException;
    import org.springframework.core.convert.converter.Converter;
    /**
     * 
     * @author 景佩佩
     *
     *S:Source 源类型
     *T:Target 目标类型
     */
    public class MyDateConverter implements Converter<String, Date> {
    
        public Date convert(String source) {
            //SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
            SimpleDateFormat sdf=getDateFormat(source);
            try {
                return sdf.parse(source);
            } catch (ParseException e) {
                //e.printStackTrace();
            }
            return null;
        }
    
        private SimpleDateFormat getDateFormat(String source){
            //一个字符串和一个特定形式能否匹配,正则
            SimpleDateFormat sdf=new SimpleDateFormat();
            if (Pattern.matches("^\d{4}-\d{2}-\d{2}$", source)) {
                sdf=new SimpleDateFormat("yyyy-MM-dd");
            }else if (Pattern.matches("^\d{4}/\d{2}/\d{2}$", source)) {
                sdf=new SimpleDateFormat("yyyy/MM/dd");
            }else if (Pattern.matches("^\d{4}\d{2}\d{2}$", source)) {
                sdf=new SimpleDateFormat("yyyyMMdd");
            }
            return sdf;
        }
        
    }

    效果:

    表单数据填错后返回表单页面

    当数据类型转换发生异常后,需要返回到表单页面,让用户重写填写,但实际情况是发生类型转化异常,系统会自动跳转到400页面。所以,若要在发生类型转换异常后,跳转到指定页面,在需要将异常捕获,然后通过异常处理器跳转到指定页面。
       需要注意的是:SimpleMappingExceptionResolver捕获的是处理器方法在执行过程中发生的异常,而类型转换异常发生在处理器方法执行之前。所以使用SimpleMappingExceptionResolver将无法捕获到类型转换异常。但注解式异常处理是可以获取到类型转换异常的。所以这里需要使用注解式异常处理。
        当请求参数的值与接收该参数的处理器方法形参类型不匹配时,会抛出类型匹配有误异常:TypeMismatchException.

    当我们在前台输入如下信息 ,年龄为string不能装配成后台的int类型转向400错误页面,

    面对这种情况我们更想看到的是回到初始页面

    我们就采用异常处理机制,其实再出现类型转换异常时,请求就不会再进入处理器方法,而是被我们自定的的异常处理方法所捕获

     在处理器类中加入异常处理方法,完成重定向的功能

    在MyController.java中

    关于表单内容填写错误转向表单本身原理

    数据回显

    在异常处理器中,通过request.getParameter()将用户输入的表单原始数据获取到,直接放入到ModelAndView中的Model中,然后从要转向的页面中就可以直接通过EL表达式读取出来,也就实现了数据回显

    其它代码都与上述一样我们会发现一个规律,利于我们进行特定数据异常的定位 所以下面我们使用ex.getMessage().contains(birthday)

    只需在MyController.java

    我们会发现一个规律,利于我们进行特定数据异常的定位 所以下面我们使用ex.getMessage().contains(birthday)

     

    index.jsp

  • 相关阅读:
    Linux C下的正则表达式
    中英文i18 vue参数传递
    es map的用法
    webpack中publicPath问题
    prop中如何获取vue data中的数据 中英文方案
    利用map reduce方法将对象转成数组
    WPF 踩坑笔记2
    WPF 踩坑笔记1
    RabbitMQ 高阶用法 之 x-expire 过期时间设置
    JANUSEC应用网关1.0发布,提供一站式安全交付能力
  • 原文地址:https://www.cnblogs.com/jingpeipei/p/6253360.html
Copyright © 2011-2022 走看看