Spring флажок JSP Tag не работает при использовании конвертера для типа Boolean - PullRequest
5 голосов
/ 04 июля 2011

Я установил веб-приложение CRUD с Spring Roo и Spring MVC.Моя проблема заключается в том, что, поскольку я использую конвертер для локализации отображения логических значений, флажок Spring JSP Tag не работает, что означает, что флажки не принимают реальное значение от компонентов бина.Они всегда ложные и не проверяются.

Я провел некоторое исследование и, вероятно, обнаружил ошибку в методе writeTagDetails org.springframework.web.servlet.tags.form.CheckboxTag .Вот интересная часть этого метода:

// the concrete type may not be a Boolean - can be String
if (boundValue instanceof String) {
    boundValue = Boolean.valueOf((String) boundValue);
}
Boolean booleanValue = (boundValue != null ? (Boolean) boundValue : Boolean.FALSE);
renderFromBoolean(booleanValue, tagWriter);

Поскольку я использую конвертер для отображения да / нет вместо true / false, boundValue является строкой и вызовом Boolean.valueOf всегда приводит к значению false, поскольку метод valueOf не знает об используемом Spring Converter и интерпретирует yes / no как false.

Как решить проблемуэто проблема с весной?У кого-нибудь есть подсказка?Мой мозг зашел в тупик.

Просто для полноты: преобразователь для логического типа работает как положено (см. Код ниже).

public class BooleanConverter implements Converter<Boolean,String>, Formatter<Boolean> {

@Autowired
private MessageSource messageSource;

@Override
public String print(Boolean object, Locale locale) {
    return (object)
            ? messageSource.getMessage("label_true", null, LocaleContextHolder.getLocale())
            : messageSource.getMessage("label_false", null, LocaleContextHolder.getLocale());
}

@Override
public String convert(Boolean source) {
    return this.print(source, null);
}
}

Ответы [ 3 ]

3 голосов
/ 28 ноября 2011

Это кажется возможным преодолеть. То есть вы хотите, чтобы удобочитаемый форматировщик отображал пользователю да / нет для логических значений в модели. Но вы все еще хотите, чтобы элементы HTML флажка работали, и кажется, что эти элементы флажка HTML / виджеты / теги JSP ожидают, что будет использоваться строка истина / ложь (или логический тип Java), и не использует конвертер для получения произвольного Строка yes / no возвращается к логическому типу.

Эта проблема для меня проявляется в том, что начальное состояние флажка никогда не ставится, когда в модели установлено значение Boolean.TRUE. Это означает, что любое чтение-изменение-обновление записи (без редактирования это поле заканчивается переходом из «истинного» в «ложное», когда оно не было изменено пользователем). Это связано с тем, что начальное состояние в пользовательском интерфейсе несовместимо с моделью (оно всегда показывает непроверенное, то есть ложное состояние), даже когда модель является истинным состоянием. Отображаемое значение имеет не отмеченный флажок на экране записи редактирования HTML, даже если для модели задано значение Boolean.TRUE для этого значения. Это связано с тем, что «да» не интерпретируется как «true» элементами HTML-флажков, и по умолчанию оно равно false (так как это логическое значение по умолчанию).

Итак, определите ваш форматтер / конвертер (как вы уже делаете). Но в свой @Controller добавьте:

@InitBinder
public void initBinder(WebDataBinder binder) {
    binder.registerCustomEditor(Boolean.class, "friesWithThat", new CustomBooleanEditor(false));
}

Похоже, что отображаемое значение строки продолжает оставаться да / нет, но значение, используемое и переданное элементу HTML-флажка, остается истинным / ложным.

Теперь при редактировании / обновлении записи (в CRUD) исходное состояние флажка согласуется с моделью, и сохранение данных (без редактирования каких-либо полей) не изменяет состояние флажка (как я понимаю проблему, с которой вы столкнулись). есть).

Итак, из этого, я думаю, мы можем понять, что конвертеры / форматеры предназначены для общего отображения данных, а PropertyEditors - для отображения данных модели таким образом, чтобы данные требовались виджету пользовательского интерфейса.

1 голос
/ 19 июня 2013

В дополнение к предыдущему ответу, начиная с весны 3.2, вы можете зарегистрировать редактор свойств для всех контроллеров и всех логических полей следующим образом:

package your.package.path;

import org.springframework.beans.propertyeditors.CustomBooleanEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.context.request.WebRequest;

@ControllerAdvice
public class GlobalBindingInitializer {

    @InitBinder
    public void registerCustomEditors(WebDataBinder binder, WebRequest request) {
        binder.registerCustomEditor(Boolean.class, new CustomBooleanEditor(false));
    }
}

если вы пришли из базовой конфигурации Spring Roo, не забудьте также добавить эту строку в ваш webmvc-config.xml

    <context:include-filter expression="org.springframework.web.bind.annotation.ControllerAdvice" type="annotation"/>

как это:

<context:component-scan base-package="your.package.path" use-default-filters="false">
    <context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
    <context:include-filter expression="org.springframework.web.bind.annotation.ControllerAdvice" type="annotation"/>
</context:component-scan>
1 голос
/ 06 июля 2011

Возможно, вы должны написать свой собственный тип с именем Choice, который имеет Choice.YES и Choice.NO в качестве порядковых перечислений, которые соответствуют 1 или 0 на основе значений, хранящихся в базе данных.

Тогда вы можетеиметь собственные отображаемые теги и входные теги, определенные в приложении для этого типа, что решит эту проблему.

...