Статьи

Интеграция Spring & JSF: конвертеры

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

Spring 3 представил совершенно новую платформу преобразования, которая позволяет преобразовывать объекты любого типа в любой другой тип (при условии, что соответствующий преобразователь зарегистрирован). Кит Дональд написал о том, как работает новый процесс преобразования . Spring MVC также был обновлен до версии 3, чтобы использовать службу конвертера при работе с параметрами запроса, например, передав параметр String в следующий метод контроллера:

1
2
@RequestMapping
public void example(@RequestParam Integer value)

приведет к выполнению конвертера StringToNumber (через StringToNumberConverterFactory ) для создания эквивалентного Integer .
В отличие от Spring, преобразователи в JSF имеют дело только с преобразованием объектов в и из Строк. Интерфейс javax.faces.convert.Converter определяет два метода: getAsString (используется при рендеринге) преобразует объект в строку, а getAsObject (используется при декодировании getAsObject ) преобразует ранее визуализированную строку обратно в объект.

По умолчанию вы можете зарегистрировать конвертеры в JSF, добавив записи в файл @FacesConverter faces-config.xml или используя аннотацию @FacesConverter . Я работал над тем, чтобы вы также могли зарегистрировать JSF-конвертеры, просто объявив их как Spring bean-компоненты. Использование Spring beans дает вам ряд преимуществ по сравнению с vanilla JSF. Например, вы легко можете внедрить другие bean-компоненты для совместной работы и использовать Spring AOP. Чтобы использовать bean-компонент конвертера, просто обратитесь к его идентификатору из JSF:

1
2
3
4
5
6
@Component
public class MyConverter implements Converter {
    @Autowire
    private MyHelper helper;
    ...
}
1
2
3
<h:inputText value=”#{bean.value}”>
    <f:converter converterId=”myConverter”/>
</h:inputText>

Чтобы сохранять ссылки на один и тот же идентификатор конвертера снова и снова, JSF позволяет вам зарегистрировать конвертер «для» определенного класса. Для поддержки этого с Spring была введена новая аннотация @ForClass :

1
2
3
4
5
@Component
@ForClass(MyCustomType.class)
public class MyConverter implements Converter {
    ...
}

В приведенном выше примере MyConverter будет использоваться каждый раз, когда объект MyCustomType нуждается в преобразовании.

Для удобства я также предоставил вариант javax.faces.convert.Converter который поддерживает дженерики. Интерфейс org.springframework.springfaces.convert.Converter имеет идентичную подпись для стандартной версии JSF. При использовании этого интерфейса с @ForClass вы также можете опустить значение в аннотации:

1
2
3
4
5
@Component
@ForClass
public class MyConverter implements Converter<MyCustomType> {
    ...
}

Вы также можете реализовать более сложные привязки «для класса», используя интерфейс ConditionalForClass (подробности см. В JavaDoc ).

Наконец, есть также поддержка использования преобразователей JSF (независимо от того, как они зарегистрированы) из Spring MVC. GenericFacesConverter является Spring ConditionalGenericConverter который при регистрации автоматически делегирует JSF.

Например, предполагая, что MyConverter зарегистрирован для MyCustomType будет работать следующее сопоставление MVC:

1
2
3
4
@RequestMapping("/example")
public void example(@RequestParam MyCustomType value) {
    ....
}

Вы также можете использовать аннотацию @FacesConverterId если вам нужно сослаться на конкретный конвертер JSF:

1
2
3
4
@RequestMapping("/example")
public void example(@RequestParam @FacesConverterId("myOtherConverter") MyOtherCustomType value) {
    ....
}

Если вы хотите увидеть это в действии, взгляните на ConverterExampleController из демонстрационного приложения .

Ссылка: Интеграция Spring & JavaServer Faces: Конвертеры от нашего партнера JCG Филиппа Уэбба в блоге Фила Уэбба в блоге.