Статьи

Scala 4 Spring MVC без Web.XML: конфигурация класса WebConfig с локализацией

В моей предыдущей статье я писал о  Scala 4 Spring MVC без Web.XML  и о том, как обрабатывать статические ресурсы, доступные клиенту AngularJS. В этой статье я покажу, как подключить приложение к Apache Tiles 3.0. Apache Tiles позволяет определять фрагменты страниц и объединять их в один. В целом Tiles 3.0 — это хороший и чистый способ многократного использования передних частей. Одной из этих частей являются локализованные сообщения (см. Рис. 1: Структура проекта).

 

Включение Apache Tiles3 требует немного больше изменений в конфигурации проекта (рис.1). Класс Scala WebConfig должен быть расширен с помощью  WebMvcConfigurerAdapter ( предыдущая статья  )

Мы также определяем набор аннотаций, которые нам нужно отсканировать по пакету проекта. Причина такого определения — показать возможности настройки Scala самой Spring Framework.

@Configuration
@ComponentScan(basePackages = Array("miko.scala.helloexample"), useDefaultFilters = false, includeFilters = Array(
  new ComponentScan.Filter(`type` = FilterType.ANNOTATION,
    value = Array(classOf[Controller], classOf[Service]))))
@EnableWebMvc
class WebConfig extends WebMvcConfigurerAdapter{
...

В  WebConfig  мы заменяем  @Bean setupViewResolver (),  который реализует   интерфейс ViewResolver, который позволяет напрямую разрешать имена символических представлений, на  getTilesConfigurer  @Bean , который предоставляет  TilesConfigurer

Класс  TilesConfigurer  предоставляет механизм заманчивости для веб-проекта (приложения), использующего JSP и другие интерфейсные движки. 

@Bean
def getTilesConfigurer: TilesConfigurer = {
  val configurer:TilesConfigurer = new TilesConfigurer()
  configurer.setCheckRefresh(true)
  configurer.setDefinitions({"/WEB-INF/pages/tiles.xml"})
  configurer
}

Кроме того, мы должны определить  ViewResolver  для плиток с помощью getTilesViewResolver @Bean  description  .

@Bean
def getTilesViewResolver: ViewResolver = {
  val resolver:TilesViewResolver = new TilesViewResolver()
  resolver.setContentType("text/html")
  resolver
}

Полная конфигурация должна определить и переопределить также пару других  Бинов,  связанных с нашим намерением локализации (l10n / l18n). Окончательный класс WebConfig Scala будет выглядеть следующим образом.

@Configuration
@ComponentScan(basePackages = Array("miko.scala.helloexample"), useDefaultFilters = false, includeFilters = Array(
  new ComponentScan.Filter(`type` = FilterType.ANNOTATION,
    value = Array(classOf[Controller], classOf[Service]))))
@EnableWebMvc
class WebConfig extends WebMvcConfigurerAdapter{

  private val logger = LoggerFactory.getLogger(getClass)

  override def configureDefaultServletHandling(configurer: DefaultServletHandlerConfigurer) = {
    configurer.enable()
  }

  override def addViewControllers(registry: ViewControllerRegistry): Unit ={
    registry.addViewController("/")
  }

  @Bean
  def getTilesViewResolver: ViewResolver = {
    val resolver:TilesViewResolver = new TilesViewResolver()
    resolver.setContentType("text/html")
    resolver
  }

  @Bean
  def getTilesConfigurer: TilesConfigurer = {
    val configurer:TilesConfigurer = new TilesConfigurer()
    configurer.setCheckRefresh(true)
    configurer.setDefinitions({"/WEB-INF/pages/tiles.xml"})
    configurer
  }

  override def addInterceptors(registry:InterceptorRegistry) = {
    val localeChangeInterceptor = new LocaleChangeInterceptor()
    localeChangeInterceptor.setParamName("lang")
    registry.addInterceptor(localeChangeInterceptor)
  }

  /**
   * equivalents for <mvc:resources> tags
   * @param registry
   */
  override def addResourceHandlers(registry: ResourceHandlerRegistry) = {
    logger.debug("Resources HANDLER")
    registry.addResourceHandler("/app/**").addResourceLocations("/app/").setCachePeriod(31550522)
    registry.addResourceHandler("/WEB-INF/layouts/**").addResourceLocations("/WEB-INF/layouts/").setCachePeriod(31550522);
    registry.addResourceHandler("/WEB-INF/pages/template/**").addResourceLocations("/WEB-INF/pages/template/").setCachePeriod(31550522);
  }

  @Bean(name = Array("localeResolver"))
  def getLocaleResolver: LocaleResolver = {
    val cookieLocaleResolver: CookieLocaleResolver = new CookieLocaleResolver()
    cookieLocaleResolver.setDefaultLocale(new Locale("en"))
    cookieLocaleResolver
  }

  override def configureContentNegotiation(configurer: ContentNegotiationConfigurer) = {
    configurer.favorPathExtension(true).ignoreAcceptHeader(true)
        .useJaf(false).defaultContentType(MediaType.TEXT_HTML)
        .mediaType("html", MediaType.TEXT_HTML)
        .mediaType("xml", MediaType.APPLICATION_XML)
        .mediaType("json", MediaType.APPLICATION_JSON)
  }

  @Bean(name = Array("messageSource"))
  def getMessageSource: MessageSource = {
    val msgSrc:ReloadableResourceBundleMessageSource = new ReloadableResourceBundleMessageSource()
    msgSrc.setBasename("classpath:/messages/message")
    msgSrc
  }
}

После включения Tiles с l10n / l18n на задней стороне мы можем перейти к front-end и сообщить Tiles, какой тип шаблона он должен использовать для правильного отображения страниц для пользователя ( рис.1. ~ Структура проекта ). Конечно, с CSS или возможными библиотеками JavaScript. 

Но я сделаю это в следующем сообщении в блоге. 

Теперь наслаждайтесь настройкой вашего класса WebConfig scala. ( мои блоги о скале )