Spring 3 PropertyEditorSupport setAsText未被客观化客户编辑器调用

时间:2012-04-25 22:36:18

标签: java spring google-app-engine spring-mvc objectify

我正在使用春天,我有一个带有客体化关键对象的儿童模型 - “关键父母”

当加载表单时,getAsText打印正常,但是当表单提交时,将跳过setAsText。任何原因?并且当它到达Controller时,parentType为空。它是表单问题或控制器还是编辑器?

(旁道:是否有为Objectify Key< - >字符串映射编写的编辑器?)

JSP

<form:hidden path="parentType"  />

控制器

    @InitBinder
    protected void initBinder(HttpServletRequest request,
            ServletRequestDataBinder binder) throws Exception {


        /** Key Conversion **/
        binder.registerCustomEditor(com.googlecode.objectify.Key.class,  new KeyEditor());
}
@RequestMapping(value = "/subtype-formsubmit", method = RequestMethod.POST)
    public ModelAndView subTypeFormSubmit(@ModelAttribute("productSubType") @Valid ProductSubType productSubType,
            BindingResult result){
        ModelAndView mav = new ModelAndView();

        //OK, getting the value
        log.info(productSubType.getType()); 

            //NOT OK, productSubType.getParentType() always null, and setAsText is not called?!
        log.info(productSubType.getParentType().toString()); 

        return mav;
    }

KeyEditor.java

public class KeyEditor extends PropertyEditorSupport {

private static final Logger log = Logger
        .getLogger(KeyEditor.class.getName());

public KeyEditor(){
    super();
}

@Override
public String getAsText() {
    Long id = ((Key) getValue()).getId();
    String kind = ((Key) getValue()).getKind();
    log.info(kind + "." + id.toString());
    return kind + "." + id.toString();
}

@Override
public void setAsText(String text) throws IllegalArgumentException {
    log.info(text);
    String clazz = text.substring(0, text.indexOf("."));
    Long id = Long.parseLong(text.substring(text.indexOf(".")));
    log.info(clazz+":"+id);
    Class c=null;
    Key<?> key=null;
    try {
        c = Class.forName(clazz);
        key = new Key(c, id);
    } catch (Exception ex) {
        log.info("ex" + ex.toString());
        ex.printStackTrace();
    }

    setValue(key);
}

}

1 个答案:

答案 0 :(得分:0)

您需要使用完整的类名称调用Class.forName,包括包。

我认为Key#getKind()返回没有包的简单类名。此外text.substring(0, text.indexOf("."));(在setAsText中)告诉我clazz中没有点,因此您没有向Class.forName提供正确的输入

选项:

  • 如果您的所有类都在同一个包中,那么只需将其添加到clazz(不是一个非常强大的解决方案)
  • 由于您无论如何都必须注册所有实体(ObjectifyService.register(YourEntity.class);),因此您可以同时创建从种类到完整类名的地图,然后在setAsText中使用它。

但可能会有更好的选择......