Связывание даты 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 может помочь, но все равно то же самое.
Я не могу и не буду верить в то, что нужно извлечь дату вручную!
Ответы
Ответ 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' действительно важно (чтобы переопределить преобразователь дат по умолчанию)