Spring MVC PropertyEditorSupport用于复杂类型

时间:2015-07-28 12:01:50

标签: java spring spring-mvc

我正在尝试将字符串日期(由html论坛提交)转换为Long类型(时间戳)。据我所知,我必须做的是创建一个自定义PropertyEditor,我做了。

我也在使用@Valid注释和自定义Validator类进行绑定。虽然我已经注册了我的PropertyEditor和Validator,但PropertyEditor将不起作用。

根据控制台输出,Validator启动并尝试验证对象,当它发现时间字符串不长时,它会将“typeMismatch”错误添加到Errors对象...

我做错了吗?

以下是课程:

控制器类

@InitBinder
public void initBinder(WebDataBinder binder)
{
    binder.registerCustomEditor(VisitorRequestBaseMVVM.class,"startingTime",new StringToLongPropertyEditorSupport());
    //I also have tried this...
    //binder.registerCustomEditor(VisitorRequestBase.class,"startingTime",new StringToLongPropertyEditorSupport());


@RequestMapping(value="/create-request",method=RequestMethod.POST)
public ModelAndView postCreateRequest(@ModelAttribute("command") @Valid VisitorRequestBaseMVVM model,
        BindingResult result)
{
    ModelAndView modelAndView = new ModelAndView("create-request-first-step");

    // For to see output of all errors      
    for(ObjectError error : result.getAllErrors())
    {
        System.out.println(error.getObjectName() + ":" + error.getCode() + ":" + error.getDefaultMessage());
    }


    VisitorRequestBaseMVVM mvvm = new VisitorRequestBaseMVVM();
    mvvm.setVisitorRequestBase(new VisitorRequestBase());
    mvvm.setAllVisitorRequestTypes(allVisitorRequestTypes());

    modelAndView.addObject("command",mvvm);

    return modelAndView;
}

    binder.addValidators(new VisitorRequestBaseMVVMValidatorImpl());
}

StringToLongPropertyEditorSupport.java

public class StringToLongPropertyEditorSupport extends
        PropertyEditorSupport {

     @Override
     public void setAsText(String text) {
         System.out.println("Has it come to this ? (StringToDateTimePropertyEditorSupport):" + text );
         setValue(DateTime.parse(text).getMillis());
     }
}

VisitorRequestBase.java

public class VisitorRequestBase extends BaseEntity{
private long startingTime;
private long endingTime;
private String note;
private boolean isCompleted;

@Enumerated(EnumType.STRING)
private ApprovalState approvalState;

@OneToOne
private User user;

private List<ApprovalHistory> approvalHistories;

public long getStartingTime() {
    return startingTime;
}
public void setStartingTime(long startingTime) {
    this.startingTime = startingTime;
}
public long getEndingTime() {
    return endingTime;
}
public void setEndingTime(long endingTime) {
    this.endingTime = endingTime;
}
public String getNote() {
    return note;
}
public void setNote(String note) {
    this.note = note;
}
public ApprovalState getApprovalState() {
    return approvalState;
}
public void setApprovalState(ApprovalState approvalState) {
    this.approvalState = approvalState;
}
public User getUser() {
    return user;
}
public void setUser(User user) {
    this.user = user;
}
public List<ApprovalHistory> getApprovalHistories() {
    return approvalHistories;
}
public void setApprovalHistories(List<ApprovalHistory> approvalHistories) {
    this.approvalHistories = approvalHistories;
}
public boolean isCompleted() {
    return isCompleted;
}
public void setCompleted(boolean isCompleted) {
    this.isCompleted = isCompleted;
}


public void setPropertiesForSubclass(final VisitorRequestBase subObject) 
        throws IllegalArgumentException, IllegalAccessException
{
    for(Field field : VisitorRequestBase.class.getFields())
    {
        field.set(subObject, field.get(this));
    }
}

}

VisitorRequestBaseValidator.java

@Component
public class VisitorRequestBaseValidatorImpl implements VisitorRequestBaseValidator {

@Override
public boolean supports(Class<?> arg0) {
    return VisitorRequestBase.class.isAssignableFrom(arg0);
}

@Override
public void validate(Object objectToValidate, Errors errors) {

    ValidationUtils.rejectIfEmptyOrWhitespace(errors, "startingTime","validation.createRequest.startingTime.empty");
}

}

VisitorRequestBaseMVVM.java

public class VisitorRequestBaseMVVM {
private VisitorRequestBase visitorRequestBase;
private VisitorRequestType visitorRequestType;

private List<VisitorRequestType> allVisitorRequestTypes;

public VisitorRequestBase getVisitorRequestBase() {
    return visitorRequestBase;
}
public void setVisitorRequestBase(VisitorRequestBase visitorRequestBase) {
    this.visitorRequestBase = visitorRequestBase;
}
public VisitorRequestType getVisitorRequestType() {
    return visitorRequestType;
}
public void setVisitorRequestType(VisitorRequestType visitorRequestType) {
    this.visitorRequestType = visitorRequestType;
}
public List<VisitorRequestType> getAllVisitorRequestTypes() {
    return allVisitorRequestTypes;
}
public void setAllVisitorRequestTypes(List<VisitorRequestType> allVisitorRequestTypes) {
    this.allVisitorRequestTypes = allVisitorRequestTypes;
}


}

VisitorRequestBaseMVVMValidatorImpl.java

@Component
public class VisitorRequestBaseMVVMValidatorImpl implements VisitorRequestBaseMVVMValidator{


@Autowired
private VisitorRequestBaseValidator visitorRequestBaseValidator;

@Override
public boolean supports(Class<?> clazz) {
    return VisitorRequestBaseMVVM.class.isAssignableFrom(clazz);
}

@Override
public void validate(Object target, Errors errors) {
    VisitorRequestBaseMVVM object = (VisitorRequestBaseMVVM)target;


    if(object.getVisitorRequestType() == null) 
        errors.rejectValue("visitorRequestType", "validation.createRequest.visitorRequestType.notSelected");


    errors.pushNestedPath("visitorRequestBase");
    ValidationUtils.invokeValidator(visitorRequestBaseValidator,object.getVisitorRequestBase(), errors);
    errors.popNestedPath();

}

 }

更新

在这些更改之后,我可以将String转换为Long

  • 我在VisitorRequestBase
  • 中将原始类型long更改为引用类型Long
  • 我已经创建了Converter并通过此代码注册到应用程序的上下文。

        <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
            <property name="converters">
                <list>
                    <bean class="com.test.mvvm.converters.StringToLongConverter"/>
                </list>
            </property>
        </bean>
    
    
        <mvc:annotation-driven conversion-service="conversionService" />
    

1 个答案:

答案 0 :(得分:0)

更改

binder.registerCustomEditor(VisitorRequestBaseMVVM.class,"startingTime",new StringToLongPropertyEditorSupport());

 binder.registerCustomEditor(VisitorRequestBaseMVVM.class,"visitorRequestBase.startingTime",new StringToLongPropertyEditorSupport());

在VisitorRequestBaseMVVM上没有字段startingTime,因此请指定该字段的嵌套路径