V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zeal7s
V2EX  ›  Java

请教一个 Spring MVC 表单提交的问题

  •  
  •   zeal7s · 2017-04-12 13:37:42 +08:00 · 2448 次点击
    这是一个创建于 2812 天前的主题,其中的信息可能已经有所发展或是发生改变。

    问题描述: 前端网页有一个包含十来个 field 的表单。 后端的 Spring MVC 的 Controller 中处理表单的代码类似这样:

    @RequestMapping(value = "edit", method = POST)
    public String doPost(@Nonnull final Student student) {
    	...
    }
    

    Student 类中有一个 field 是 boolean 类型。现在有一个需求,转换表单中的某一个 String 成为 Student 中的 boolean 属性。转换过程比较复杂,所以需要自定义转换的代码。

    楼主 Google 了好久,发现使用 PropertyEditorSupport 可能可以解决这个问题,于是首先自定义了一个 PropertyEditor :

    public class MyEditor extends PropertyEditorSupport {
    	@Override
        public void setAsText(final String text) throws IllegalArgumentException {
        	final boolean b = ....
            setValue(b);
        }
    }
    

    然后在 Controller 中注册 MyEditor ,代码如下:

    @InitBinder
    protected void initBinder(final WebDataBinder binder) {
    	binder.registerCustomEditor(boolean.class, new MyEditor());
        binder.registerCustomEditor(Boolean.class, new MyEditor());
    }
    

    以防万一, boolean 和 Boolean 都注册了。 运行代码,发现 initBinder 被调用了,但是 setAsText 没有被调用。 楼主又写了一个只有一个 field 的简单表单,测试看看是否注册 MyEditor 注册成功,代码如下:

    @RequestMapping(value = "/test", method = POST)
    public String test(final boolean test) {
    	...
    }
    

    对于这个简单的 controller 方法, setAsText 有被调用。 所以问题是出现在哪里呢?如何解决表单提交时自定义 field 绑定的问题?谢谢~

    3 条回复    2017-04-12 16:46:51 +08:00
    ixx
        1
    ixx  
       2017-04-12 14:15:02 +08:00
    看了一下你理解的可能不太对
    binder.registerCustomEditor(boolean.class, new MyEditor());
    这里注册的是在哪种类型的参数使用该属性编辑器,这就是为什么你单独定义一个 boolean 时 setAsText 被调用的原因
    除非你自己定义一个完全解析前台传入的参数封装为 Student 类型返回的 MyEditor 再把它注册为 binder.registerCustomEditor(Student.class, new MyEditor());

    或者你可以换个思路,加一个 StudentRequest 类在里边加一个接收这个 String 类型的字段,然后在 doPost 方法内去创建一个 Student 方法,对应的 Boolean 字段你需要怎么判断 set 值都可以
    yang2yang
        2
    yang2yang  
       2017-04-12 15:48:19 +08:00
    你这样的话,就会导致所有的 boolean 和 Boolean 都会调用你这个转换的函数吧?
    其实,是不是可以先用一个正常的 String 字段接收,然后在进行逻辑的判断和转换?
    wc951
        3
    wc951  
       2017-04-12 16:46:51 +08:00 via Android
    用个 dto 去接数据吧,费这么大力气还不如取到数据再做映射
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3965 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 01:00 · PVG 09:00 · LAX 17:00 · JFK 20:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.