Учебные материалы

Обработка настроек сайта

В этом уроке освещается процесс использования Spring для предоставления пользователю выбор отображения вашего сайта, нормальная, мобильная или версия для планшетов, независимо от того, какое устройство используется для просмотра.

Что вы создадите

Вы создадите Spring MVC приложение, которое определяет тип устройства, с которого осуществляется доступ к вашему сайту и включает функциональность для переопределения представления по умолчанию для устройства, выбранного как альтернативная настройка сайта.

Что вам потребуется

  • Примерно 15 минут свободного времени
  • Любимый текстовый редактор или IDE
  • JDK 6 и выше
  • Gradle 1.11+ или Maven 3.0+
  • Вы также можете импортировать код этого урока, а также просматривать web-страницы прямо из Spring Tool Suite (STS), собственно как и работать дальше из него.

Как проходить этот урок

Как и большинство уроков по Spring, вы можете начать с нуля и выполнять каждый шаг, либо пропустить базовые шаги, которые вам уже знакомы. В любом случае, вы в конечном итоге получите рабочий код.

Чтобы начать с нуля, перейдите в Настройка проекта.

Чтобы пропустить базовые шаги, выполните следующее:

Когда вы закончите, можете сравнить получившийся результат с образцом в gs-handling-site-preference/complete.

Настройка проекта

Для начала вам необходимо настроить базовый скрипт сборки. Вы можете использовать любую систему сборки, которая вам нравится для сборки проетов Spring, но в этом уроке рассмотрим код для работы с Gradle и Maven. Если вы не знакомы ни с одним из них, ознакомьтесь с соответсвующими уроками Сборка Java-проекта с использованием Gradle или Сборка Java-проекта с использованием Maven.

Создание структуры каталогов

В выбранном вами каталоге проекта создайте следующую структуру каталогов; к примеру, командой mkdir -p src/main/java/hello для *nix систем:

└── src
    └── main
        └── java
            └── hello

Создание файла сборки Gradle

Ниже представлен начальный файл сборки Gradle. Файл pom.xml находится здесь. Если вы используете Spring Tool Suite (STS), то можете импортировать урок прямо из него.

Если вы посмотрите на pom.xml, вы найдете, что указана версия для maven-compiler-plugin. В общем, это не рекомендуется делать. В данном случае он предназначен для решения проблем с нашей CI системы, которая по умолчанию имеет старую(до Java 5) версию этого плагина.

build.gradle

buildscript {
    repositories {
        maven { url "http://repo.spring.io/libs-release" }
        mavenLocal()
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.1.9.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'

jar {
    baseName = 'gs-handling-site-preference'
    version =  '0.1.0'
}

repositories {
    mavenLocal()
    mavenCentral()
    maven { url "http://repo.spring.io/libs-release" }
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    compile("org.springframework.boot:spring-boot-starter-mobile")
}

task wrapper(type: Wrapper) {
    gradleVersion = '1.11'
}

Spring Boot gradle plugin предоставляет множество удобных возможностей:

  • Он собирает все jar'ы в classpath и собирает единое, исполняемое "über-jar", что делает более удобным выполнение и доставку вашего сервиса
  • Он ищет public static void main() метод, как признак исполняемого класса
  • Он предоставляет встроенное разрешение зависимостей, с определенными номерами версий для соответсвующих Spring Boot зависимостей. Вы можете переопределить на любые версии, какие захотите, но он будет по умолчанию для Boot выбранным набором версий

Автоконфигурация

Spring Boot автоматически настраивает три класса: DeviceResolverHandlerInterceptor, SitePreferenceHandlerInterceptor и SitePreferenceHandlerMethodArgumentResolver. DeviceResolverHandlerInterceptor реализует HandlerInterceptor, который, как следует из названия, перехватывает запрос к приложению и определяет тип запрашиваемого устройства. После того, как устройство определено, SitePreferenceHandlerMethodArgumentResolver позволяет Spring MVC использовать соответствующий объект SitePreference в методе контроллера.

В своей работе DeviceResolverHandlerInterceptor анализирует заголовок User-Agent во входящем запросе и на основе полученного значения определяет, что запрос пришел от обычного(desktop), мобильного или браузера планшетного компьютера. DeviceResolverHandlerInterceptor предоставляет несколько вариантов для переопределения или настройки того, для какого устройства работать.

SitePreferenceHandlerInterceptor использует обнаруженное устройство для определения начальных настроек сайта. Если пользователь предпочитает другой сайт, то этот выбор будет использоваться и в других запросах к этому сайту. Настройка сайта устанавливается путем добавления определенного строкового параметра в запрос. Однажды полученная, настройка сохраняется в cookie как будущая настройка.

Функциональность настройки сайта включается по умолчанию в Spring Boot когда вы подключаете Spring Mobile. Однако, она может быть отключена настройкой в свойствах значением false:

src/main/resources/application.properties

# spring.mobile.sitepreference.enabled: true

Создание web контроллера

В Spring web точки выхода являются простыми Spring MVC контроллерами. Ниже приведенный Spring MVC контроллер обрабатывает GET запросы и возвращает String, указывающую на тип устройства:

src/main/java/hello/GreetingController.java

package hello;

import org.springframework.mobile.device.site.SitePreference;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class GreetingController {

    @RequestMapping("/site-preference")
    public @ResponseBody
    String home(SitePreference sitePreference) {
        if (sitePreference != null) {
            return "Hello " + sitePreference.name() + " site preference!";
        } else {
            return "SitePreference is not configured.";
        }
    }

}

В этом примере, вместо того, чтобы использовать представление(такое как JSP) для рендеринга модели данных в HTML, этот контроллер просто возвращает данные, которые записываются прямо в тело ответа, за что отвечает аннотация @ResponseBody. В этом случае данные будут выглядеть как "Hello NORMAL site preference!", если клиентский запрос был совершен из обычного браузера.

Создание приложения исполняемым

Несмотря на то, что пакет этого сервиса может быть в составе web-приложения и WAR файлов, более простой подход, продемонстрированный ниже создает отдельное самостоятельное приложение. Вы упаковываете все в единый, исполняемый JAR-файл, который запускается через хорошо знакомый старый main() Java-метод. Попутно, вы используете поддержку Spring для встроенного Tomcat контейнера сервлетов как HTTP среду выполнения вместо развертывания на сторонний экземпляр.

src/main/java/hello/Application.java

package hello;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan
@EnableAutoConfiguration
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

Метод main() передает управление вспомогательному классу SpringApplication, предоставляя Application.class как аргумент его run() методу. Это говорит Spring о том, чтобы прочитать аннотацию метаданных из Application и управлять им как компонентом в Spring Application Context.

Аннотация @ComponentScan сообщает Spring о запуске рекурсивного поиска в пакете hello и потомках классов, отмеченных прямо или косвенно Spring аннотацией @Component. При этом гарантируется, что Spring найдет и зарегистрирует GreetingController, потому что он отмечен @Controller, что в свою очередь является своего рода @Component аннотацией.

@EnableAutoConfiguration аннотация переключает на доступные по умолчанию настройки, основанные на содержимом вашего classpath. К примеру, т.к. приложение зависит от встраиваемой версии Tomcat(tomcat-embed-core.jar), то Tomcat сервер установлен и настроен по умолчанию от вашего имени. И также, т.к. приложение зависит от Spring MVC (spring-webmvc.jar), Spring MVC DispatcherServlet настроен и зарегистрирован за вас - web.xml не нужен! Поэтому здесь MultipartConfigElement, он настроен DispatcherServlet с функциональностью загрузки файлов. Автонастройка является мощным и гибким механизмом. Более подробно вы можете ознакомиться в API документации.

Сборка исполняемого JAR

Вы можете собрать единый исполняемый JAR-файл, который содержит все необходимые зависимости, классы и ресурсы. Это делает его легким в загрузке, версионировании и развертывании сервиса как приложения на протяжении всего периода разработки, на различных средах и так далее.

./gradlew build

Затем вы можете запустить JAR-файл:

java -jar build/libs/gs-handling-site-preference-0.1.0.jar

Если вы используете Maven, вы можете запустить приложение, используя mvn spring-boot:run, либо вы можете собрать приложение с mvn clean package и запустить JAR примерно так:

java -jar target/gs-handling-site-preference-0.1.0.jar
Процедура, описанная выше, создает исполняемый JAR. Вы также можете вместо него собрать классический WAR-файл.

Если вы используете Gradle, вы можете запустить ваш сервис из командной строки:

./gradlew clean build && java -jar build/libs/gs-handling-site-preference-0.1.0.jar
Если вы используете Maven, то можете запустить ваш сервис таким образом: mvn clean package && java -jar target/gs-handling-site-preference-0.1.0.jar.

Как вариант, вы можете запустить ваш сервис напрямую из Gradle примерно так:

./gradlew bootRun
С mvn - mvn spring-boot:run.

Данные по логгированию отображаются. Сервис должен быть поднят и запущен через несколько секунд.

Тестирование сервиса

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

http://localhost:8080/site-preference

Передавая в запрос параметр site_preference=mobile, пользователь может определить предпочтительность для мобильной версии сайта.

http://localhost:8080/site-preference?site_preference=mobile

Предпочитаемая версия сайта сохранена в куки и последующие запросы к сайту будут учитывать новую настройку без необходимости указания параметра запроса.

http://localhost:8080/site-preference

Итог

Поздравляем! Вы только что разработали простую web страницу, которая определяет тип устройства, используемое клиентом и предлагает выбор предпочитаемой версии сайта.

С оригинальным текстом урока вы можете ознакомиться на spring.io.

comments powered by Disqus