Подтвердить что ты не робот

Связывание даты Grails с параметрами в контроллере

Почему так сложно извлечь дату из представления через параметры в контроллере grails?

Я не хочу извлекать дату вручную:

instance.dateX = parseDate(params["dateX_value"])//parseDate is from my helper class

Я просто хочу использовать instance.properties = params.

В модели тип java.util.Date, а в параметрах - вся информация: [dateX_month: 'value', dateX_day: 'value', ...]

Я искал в сети и ничего не нашел на этом. Я надеялся, что Grails 1.3.0 может помочь, но все равно то же самое.

Я не могу и не буду верить в то, что нужно извлечь дату вручную!

4b9b3361

Ответ 1

Версия Grails >= 2.3

Параметр Config.groovy определяет форматы даты, которые будут использоваться в приложении во время привязки параметров к Date

grails.databinding.dateFormats = [
        'MMddyyyy', 'yyyy-MM-dd HH:mm:ss.S', "yyyy-MM-dd'T'hh:mm:ss'Z'"
]

Форматы, указанные в grails.databinding.dateFormats, будут предприняты в том порядке, в котором они включены в список.

Вы можете переопределить эти форматы приложений для отдельного объекта команды, используя @BindingFormat

import org.grails.databinding.BindingFormat

class Person { 
    @BindingFormat('MMddyyyy') 
    Date birthDate 
}

Версия Grails < 2.3

Я не могу и не буду верить, что извлечение даты вручную является обязательным!

Ваше упрямство вознаграждено, было возможно связать дату непосредственно задолго до Grails 1.3. Шаги:

(1) Создайте класс, который регистрирует редактор для формата даты

import org.springframework.beans.PropertyEditorRegistrar
import org.springframework.beans.PropertyEditorRegistry
import org.springframework.beans.propertyeditors.CustomDateEditor
import java.text.SimpleDateFormat

public class CustomDateEditorRegistrar implements PropertyEditorRegistrar {

    public void registerCustomEditors(PropertyEditorRegistry registry) {

        String dateFormat = 'yyyy/MM/dd'
        registry.registerCustomEditor(Date, new CustomDateEditor(new SimpleDateFormat(dateFormat), true))
    }
}

(2) Сделайте Grails осведомленным об этом редакторе дат, зарегистрировав следующий bean в grails-app/conf/spring/resources.groovy

beans = {
    customPropertyEditorRegistrar(CustomDateEditorRegistrar)
}

(3) Теперь, когда вы отправляете дату в параметре с именем foo в формате yyyy/MM/dd, он автоматически привязывается к свойству с именем foo, используя:

myDomainObject.properties = params

или

new MyDomainClass(params)

Ответ 2

У Grails 2.1.1 есть новый метод в параметрах для простого нейтрального безопасного анализа.

def val = params.date('myDate', 'dd-MM-yyyy')
// or a list for formats
def val = params.date('myDate', ['yyyy-MM-dd', 'yyyyMMdd', 'yyMMdd']) 
// or the format read from messages.properties via the key 'date.myDate.format'
def val = params.date('myDate')

Найти его в doc здесь

Ответ 3

Версия Grails >= 3.x

Вы можете установить в application.yml форматы даты, следующие за этим синтаксисом:

grails:
  databinding:
    dateFormats:
      - 'dd/MM/yyyy'
      - 'dd/MM/yyyy HH:mm:ss'
      - 'yyyy-MM-dd HH:mm:ss.S'
      - "yyyy-MM-dd'T'hh:mm:ss'Z'"
      - "yyyy-MM-dd HH:mm:ss.S z"
      - "yyyy-MM-dd'T'HH:mm:ssX"

Ответ 4

Вы пытались использовать любой из плагинов для выбора даты Grails?

У меня были хорошие впечатления от плагина календаря.

(При использовании плагина календаря) При отправке запроса выбора даты вы можете автоматически привязать параметр запроса к объекту домена, который вы хотите заполнить запросом.

например.

new DomainObject(params)

Вы также можете проанализировать строку даты "yyyy/MM/dd", как это...

new Date().parse("yyyy/MM/dd", "2010/03/18")

Ответ 5

@Don Спасибо за ответ выше.

Здесь альтернатива настраиваемому редактору, который проверяет дату первой даты, а затем формат даты.

Groovy, просто добавьте полуколоны обратно для java

import java.text.DateFormat
import java.text.ParseException
import org.springframework.util.StringUtils
import java.beans.PropertyEditorSupport

class CustomDateTimeEditor extends PropertyEditorSupport {
    private final java.text.DateFormat dateTimeFormat
    private final java.text.DateFormat dateFormat
    private final boolean allowEmpty

    public CustomDateTimeEditor(DateFormat dateTimeFormat, DateFormat dateFormat, boolean allowEmpty) {
        this.dateTimeFormat = dateTimeFormat
        this.dateFormat = dateFormat
        this.allowEmpty = allowEmpty
    }

    /**
     * Parse the Date from the given text, using the specified DateFormat.
     */
    public void setAsText(String   text) throws IllegalArgumentException   {
        if (this.allowEmpty && !StringUtils.hasText(text)) {
            // Treat empty String as null value.
            setValue(null)
        }
        else {
            try {
                setValue(this.dateTimeFormat.parse(text))
            }
            catch (ParseException dtex) {
                try {
                    setValue(this.dateFormat.parse(text))
                }
                catch ( ParseException dex ) {
                    throw new IllegalArgumentException  ("Could not parse date: " + dex.getMessage() + " " + dtex.getMessage() )
                }
            }
        }
    }

    /**
     * Format the Date as String, using the specified DateFormat.
     */
    public String   getAsText() {
        Date   value = (Date) getValue()
        return (value != null ? this.dateFormat.format(value) : "")
    }
}

Ответ 6

Версия Grails >= 2.3

Версия localeAware для преобразования строк на дату

В src/ groovy:

package test

import org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest
import org.grails.databinding.converters.ValueConverter
import org.springframework.context.MessageSource
import org.springframework.web.servlet.LocaleResolver

import javax.servlet.http.HttpServletRequest
import java.text.SimpleDateFormat

class StringToDateConverter implements ValueConverter {
    MessageSource messageSource
    LocaleResolver localeResolver

    @Override
    boolean canConvert(Object value) {
        return value instanceof String
    }

    @Override
    Object convert(Object value) {
        String format = messageSource.getMessage('default.date.format', null, "dd/MM/yyyy", getLocale())
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format)
        return simpleDateFormat.parse(value)
    }

    @Override
    Class<?> getTargetType() {
        return Date.class
    }

    protected Locale getLocale() {
        def locale
        def request = GrailsWebRequest.lookup()?.currentRequest
        if(request instanceof HttpServletRequest) {
            locale = localeResolver?.resolveLocale(request)
        }
        if(locale == null) {
            locale = Locale.default
        }
        return locale
    }
}

В conf/ spring/resources.groovy:

beans = {
    defaultDateConverter(StringToDateConverter){
        messageSource = ref('messageSource')
        localeResolver = ref('localeResolver')
    }
}

Значение bean 'defaultDateConverter' действительно важно (чтобы переопределить преобразователь дат по умолчанию)