我是靠谱客的博主 粗犷秋天,最近开发中收集的这篇文章主要介绍数据前置参数类型转换@InitBinder、Formatter<?>、Converter<?>的使用,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

前言:在很多时候我们在进行调用接口的时候,传入的参数类型不是指定的特别明确(或者是不能进行自动类型转换),会导致调用接口失败的情况出现,如果我们在调用接口之前进行数据格式化,手动进行数据类型转换,那么就不会出现调用接口失败的情况出现了。这些注解无非也就是做这些工作的。

下面列举工作绝大部分用到的场景

接口中的入参为book,其中book有这几个属性,且提供get、set、tostring方法,如果前端传过来的date的这个属性是一个字符串,但是后端是用Date类型接收的,那么在调用接口的时候会报错。
在这里插入图片描述

 	int id;
    String name;
    Date date;

    @ResponseBody
    @RequestMapping(value = "/bookDo", produces = "application/json"
            , consumes = "application/x-www-form-urlencoded",
            method = RequestMethod.POST)
    public book bookDo(book book) {
        return book;
    }
    @RequestMapping(value = "/date",
            method = RequestMethod.POST)
    public String date(Date date, Model model) {
        model.addAttribute("date", date);
        return "book";
    }

解决办法一(@DateTimeFormat+@JsonFormat)

@DateTimeFormat:指定前端传过来的date的格式化标准(注意前端测试数据别乱写!)
@JsonFormat:指定输出的date格式,由于格式化date是按照国际化标准时间算的,转换成中国时间需要加8


 	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(
            pattern = "yyyy-MM-dd HH:mm:ss",
            timezone = "GMT+8"
    )
    Date date;

缺点:如果有很多个类都需要进行date类型转换,每个实体类都要加这些注解,很麻烦!

解决办法二(@InitBinder+WebDataBinder )

作用:在数据绑定的时候把字符串格式化成Date类型的date,并且不对id绑定,即使前端传了id值也接收不到了哦!(WebDataBinder里面还有一些其他的方法,读者可以自行测试)

/**
 * @author 张子行
 * @class
 */
   @InitBinder
    public void bind(WebDataBinder webDataBinder) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        webDataBinder.registerCustomEditor(Date.class, new CustomDateEditor(simpleDateFormat, true));
        webDataBinder.setDisallowedFields("id");
    }

缺点:只能对当前的controller起作用,如果好多controller需要日期格式话呢?每个controller都加上这个东西也是很麻烦!

优化办法二(巧用extends特性 )

让所有需要日期转换的都extends这个类,代码量又小一点了。

/**
 * @author 张子行
 * @class
 */
public class baseController {
    @InitBinder
    public void bind(WebDataBinder webDataBinder) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        webDataBinder.registerCustomEditor(Date.class, new CustomDateEditor(simpleDateFormat, true));
        webDataBinder.setDisallowedFields("id");
    }
}

解决办法三(Formatter)

通过实现Formatter接口实现自己的日期格式化逻辑,并且加入到容器内,其中的Locale可以参考国际化解析

/**
 * @author 张子行
 * @class
 */
@Component
public class myDateFormatter implements Formatter<Date> {
    private SimpleDateFormat simpleDateFormat;
    public myDateFormatter() {
        simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    }
    /**
     * @param
     * @method 日期接收格式
     */
    @Override
    public Date parse(String s, Locale locale) throws ParseException {
        return simpleDateFormat.parse(s);
    }
    /**
     * @param
     * @method 日期对外输出格式
     */
    @Override
    public String print(Date date, Locale locale) {
        return simpleDateFormat.format(date);
    }
}

另外添加Formatter的方式有很多,通过实现WebMvcConfigurer 接口进行相关的mvc扩展配置,来添加Formatter也是可以的

/**
 * @author 张子行
 * @class
 */
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    /**
     * @method 添加Formatter
     * @param
     */
    @Override
    public void addFormatters(FormatterRegistry registry) {
        //registry.addConverter(new myDateConverter());
        registry.addFormatter(new myDateFormatter());

    }
    /**
     * @method 添加视图控制器
     * @param
     */
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {

    }
}

解决办法四(Converter)

和Formatter接口使用上差不多,但是更加强大,可转换的东西也更广。之后加@Component或者注册Converter

/**
 * @author 张子行
 * @class
 */
 @Component
public class myDateConverter implements Converter<String, Date> {
    @Override
    public Date convert(String s) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date parse = null;
        try {
            parse = simpleDateFormat.parse(s);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return parse;

    }
}

效果

数据传给后端在做显示给前端
在这里插入图片描述

扩展

如果前端传的是字符串,后端用boolean 接收,咋办呢?同理写Formatter

@RequestMapping(value = "/boolean",
            method = RequestMethod.POST)
    public String date2(boolean b, Model model) {
        model.addAttribute("boolean", b);
        return "book";
    }

只要调用这个接口,传过来的字符串是 {“是”, “嗯”}中的任意一个,那么都为true

@Component
public class myBooleanFormatter implements Formatter<Boolean> {
    private final String[] data = {"是", "嗯"};


    @Override
    public Boolean parse(String s, Locale locale) throws ParseException {
        return Arrays.asList(data).contains(s);
    }

    @Override
    public String print(Boolean aBoolean, Locale locale) {
        return aBoolean ? "true" : "false";
    }
}

测试代码读者觉着不错可以点个星星

最后

以上就是粗犷秋天为你收集整理的数据前置参数类型转换@InitBinder、Formatter<?>、Converter<?>的使用的全部内容,希望文章能够帮你解决数据前置参数类型转换@InitBinder、Formatter<?>、Converter<?>的使用所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(30)

评论列表共有 0 条评论

立即
投稿
返回
顶部