欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Register multiple date format for binding properities

程序员文章站 2022-05-19 21:46:12
...
Grails可以自动把params里面的参数绑定到domain class。有些时候为了能够绑定自定义的日期格式,例如"yyyy-MM-dd",需要register一个自己的CustomDateEditor。

有时候还有需求要绑定多种格式的日期,例如"yyyy/MM/dd"、"yyyy-MM-dd HH:mm:ss"等等,这时候就需要一个支持多种日期格式的CustomDateEditor,解决方法如下:

1. 新建一个MultipleDateEditor.groovy
package com.myapp

import java.beans.PropertyEditorSupport;
import java.text.ParseException;
import java.util.Date;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.util.StringUtils;

/**
 * Property editor for java.util.Date, supporting multiple custom input formats
 * and custom output formats.  This class utilizes DateUtils and
 * DateFormatUtils of Apache Commons Lang, and has been tested for version 2.4
 * but may work with older versions.
 *
 * It should be noted that the date input formats should be inserted into the
 * array based on the length of the string, longest to shortest.
 *
 * This is not meant to be used as system PropertyEditor but rather as
 * locale-specific date editor within custom controller code, parsing
 * user-entered number strings into Date properties of beans and rendering
 * them in the UI form.
 *
 * In web MVC code, this editor will typically be registered with
 * binder.registerCustomEditor calls in a custom initBinder method.
 *
 * @author jpreston
 * @see java.beans.PropertyEditorSupport
 * @see java.util.Date
 * @see org.apache.commons.lang.time.DateUtils
 * @see org.apache.commons.lang.time.DateFormatUtils
 */
public class MultipleDateEditor extends PropertyEditorSupport {

    /**
     * The date format used to format a Date into a String
     */
    public final static String DEFAULT_OUTPUT_FORMAT = "dd/mm/yyyy";
    /**
     * The date formats used to parse a String into a Date
     */
    public final static String[] DEFAULT_INPUT_FORMATS = [
        "dd/mm/yyyy hh:mm:ss",
        "dd-mm-yyyy hh:mm:ss",
        "dd/mm/yy hh:mm:ss",
        "dd-mm-yy hh:mm:ss",
        "dd/mm/yyyy",
        "dd-mm-yyyy",
        "dd/mm/yy",
        "dd-mm-yy"
    ];
    /** The format used to convert a Date into a String */
    private String outputFormat;
    /** An array of date formats used to convert a String into a Date */
    private String[] inputFormats;
    /** Allow empty strings to be parsed instead of treated as null */
    private boolean allowEmpty;

    /**
     * Create a new MultipleDateEditor instance using the default values
     */
    public MultipleDateEditor() {
        outputFormat = MultipleDateEditor.DEFAULT_OUTPUT_FORMAT;
        inputFormats = MultipleDateEditor.DEFAULT_INPUT_FORMATS;
        allowEmpty = false;
    }

    /**
     * Create a new MultipleDateEditor instance using the given date
     * input and output formats.
     *
     * The "allowEmpty" parameter states if an empty String should be allowed for
     * parsing, i.e. get interpreted as null value. Otherwise, an
     * IllegalArgumentException gets thrown in that case.
     *
     * @param outputFormat The format used to convert a Date into a String
     * @param inputFormats An array of date formats used to convert a String into a Date
     */
    public MultipleDateEditor(String outputFormat, String[] inputFormats) {
        this.outputFormat = outputFormat;
        this.inputFormats = inputFormats;
        allowEmpty = false;
    }

    /**
     * Create a new MultipleDateEditor instance using the given date
     * input and output formats.
     *
     * The "allowEmpty" parameter states if an empty String should be allowed for
     * parsing, i.e. get interpreted as null value. Otherwise, an
     * IllegalArgumentException gets thrown in that case.
     *
     * @param outputFormat The format used to convert a Date into a String
     * @param inputFormats An array of date formats used to convert a String into a Date
     * @param allowEmpty Allow empty strings to be parsed instead of treated as null
     */
    public MultipleDateEditor(String outputFormat, String[] inputFormats,
            boolean allowEmpty) {
        this.outputFormat = outputFormat;
        this.inputFormats = inputFormats;
        this.allowEmpty = allowEmpty;
    }

    /**
     * Format the Date as String, using the specified outputFormat.
     *
     * If allowEmpty is true (default is false), and the Date is null, an empty
     * String will be returned; otherwise it is possible that a NPE or other
     * parsing exception will occur.
     *
     * @return The string value of the Date
     */
    @Override
    public String getAsText() {
        if (allowEmpty && getValue() == null) {
            return "";
        }

        return DateFormatUtils.format((Date) getValue(), outputFormat);
    }

    /**
     * Parse the Date from the given text, using the first matching date format
     * specified in the inputFormats array.
     *
     * If no matching input format is found, an IllegalArgumentException is thrown.
     *
     * If allowEmpty is true (default is false), and the String is null, the Date
     * will be interpreted as null; otherwise an IllegalArgumentException is thrown.
     *
     * @param text the text to convert into a java.util.Date
     * @throws IllegalArgumentException thrown if no matching format is found
     */
    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        try {
            if (StringUtils.hasText(text)) {
                setValue(DateUtils.parseDate(text, inputFormats));
            } else {
                if (allowEmpty) {
                    setValue(null);
                } else {
                    throw new IllegalArgumentException(
                            "The text specified for parsing is null");
                }
            }
        } catch (ParseException ex) {
            throw new IllegalArgumentException("Could not parse text ["
                    + text + "] into any available date input formats", ex);
        }
    }

    /**
     * If allowEmpty is true (default is false), and the Date is null, an empty
     * String will be returned; otherwise it is possible that a NPE or other
     * parsing exception will occur.
     *
     * If allowEmpty is true (default is false), and the String is null, the Date
     * will be interpreted as null; otherwise an IllegalArgumentException is thrown.
     *
     * @return whether empty strings are allowed
     */
    public boolean isAllowEmpty() {
        return allowEmpty;
    }

    /**
     * If allowEmpty is true (default is false), and the Date is null, an empty
     * String will be returned; otherwise it is possible that a NPE or other
     * parsing exception will occur.
     *
     * If allowEmpty is true (default is false), and the String is null, the Date
     * will be interpreted as null; otherwise an IllegalArgumentException is thrown.
     *
     * @param allowEmpty whether empty strings should be allowed
     */
    public void setAllowEmpty(boolean allowEmpty) {
        this.allowEmpty = allowEmpty;
    }

    /**
     * Get the date formats used to parse a String into a Date
     *
     * @return The date formats used to parse a String into a Date
     */
    public String[] getInputFormats() {
        return inputFormats;
    }

    /**
     * Set the date formats used to parse a String into a Date.  It should be
     * noted that the date formats should be inserted into the array based
     * on the length of the format, longest to shortest.
     *
     *
     * @param inputFormats The date formats used to parse a String into a Date
     */
    public void setInputFormats(String[] inputFormats) {
        this.inputFormats = inputFormats;
    }

    /**
     * Get the format used to convert a Date into a String
     *
     * @return The format used to convert a Date into a String
     */
    public String getOutputFormat() {
        return outputFormat;
    }

    /**
     * Set the format used to convert a Date into a String
     *
     * @param outputFormat The format used to convert a Date into a String
     */
    public void setOutputFormat(String outputFormat) {
        this.outputFormat = outputFormat;
    }
}


2. 新建MultipleDateEditorRegistrar.groovy
package com.myapp

import org.springframework.beans.PropertyEditorRegistrar
import org.springframework.beans.PropertyEditorRegistry

/**
 * binding date properties with customer format
 * "yyyy-MM-dd HH:mm:ss"
 * "yyyy-MM-dd HH:mm"
 * "yyyy-MM-dd"
 */
public class MultipleDateEditorRegistrar implements PropertyEditorRegistrar {
  public void registerCustomEditors(PropertyEditorRegistry registry) {
      registry.registerCustomEditor(Date.class, 
new MultipleDateEditor("yyyy-MM-dd HH:mm:ss",
              ["yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM-dd"] as String[], true));
  }
}


3. 注册到spring beans
beans = {
        customPropertyEditorRegistrar(com.nazuche.MultipleDateEditorRegistrar)
}



Reference: http://forum.springsource.org/showthread.php?78118-Multiple-Date-Formats-in-a-Form

上一篇: 喝喜酒

下一篇: 和老婆怄气