Обработка данных
В этом уроке освещается процесс создания простого приложения c использованием Spring Integration, которое получает данные из Twitter, манипулирет ими, а потом пишет в файл.
Что вы создадите
Вы создадите поток c использованием Spring Integration.
Что вам потребуется
- Примерно 15 минут свободного времени
- Любимый текстовый редактор или IDE
- JDK 6 и выше
- Gradle 1.11+ или Maven 3.0+
- Вы также можете импортировать код этого урока, а также просматривать web-страницы прямо из Spring Tool Suite (STS), собственно как и работать дальше из него.
Как проходить этот урок
Как и большинство уроков по Spring, вы можете начать с нуля и выполнять каждый шаг, либо пропустить базовые шаги, которые вам уже знакомы. В любом случае, вы в конечном итоге получите рабочий код.
Чтобы начать с нуля, перейдите в Настройка проекта.
Чтобы пропустить базовые шаги, выполните следующее:
- Загрузите и
распакуйте архив с кодом этого урока, либо кнонируйте из репозитория с помощью
Git:
git clone https://github.com/spring-guides/gs-integration.git
- Перейдите в каталог
gs-integration/initial
- Забегая вперед, опишите план интеграции
Когда вы закончите, можете сравнить получившийся результат с образцом в gs-integration/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.8.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
jar {
baseName = 'gs-integration'
version = '0.1.0'
}
repositories {
mavenLocal()
mavenCentral()
maven { url "http://repo.spring.io/libs-release" }
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-integration")
compile("org.springframework.integration:spring-integration-twitter:4.0.3.RELEASE")
testCompile("junit:junit")
}
task wrapper(type: Wrapper) {
gradleVersion = '1.11'
}
Spring Boot gradle plugin предоставляет множество удобных возможностей:
- Он собирает все jar'ы в classpath и собирает единое, исполняемое "über-jar", что делает более удобным выполнение и доставку вашего сервиса
- Он ищет
public static void main()
метод, как признак исполняемого класса - Он предоставляет встроенное разрешение зависимостей, с определенными номерами версий для соответсвующих Spring Boot зависимостей. Вы можете переопределить на любые версии, какие захотите, но он будет по умолчанию для Boot выбранным набором версий
Описание плана интеграции
В этом учебном приложении вы опишите Spring Integration план, который
читает твиты из Twitter, трансформирует их в легкочитаемые String
,
а затем дабавляет их в конец файла.
Чтобы описать интеграционный план, вы просто создаете Spring XML конфигурацию из нескольких элементов пространства имен Spring Integration XML, в частности: core, twitter и file.
Ниже приведен XML файл конфигурации, описывающий план интеграции.
src/main/resources/hello/integration.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:twitter="http://www.springframework.org/schema/integration/twitter"
xmlns:file="http://www.springframework.org/schema/integration/file"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/file http://www.springframework.org/schema/integration/file/spring-integration-file-2.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration/twitter http://www.springframework.org/schema/integration/twitter/spring-integration-twitter-2.2.xsd">
<twitter:search-inbound-channel-adapter id="tweets"
query="#HelloWorld"
twitter-template="twitterTemplate">
<int:poller fixed-rate="5000"/>
</twitter:search-inbound-channel-adapter>
<int:transformer
input-channel="tweets"
expression="payload.fromUser + ' : ' + payload.text + @newline"
output-channel="files"/>
<file:outbound-channel-adapter id="files"
mode="APPEND"
charset="UTF-8"
directory="/tmp/si"
filename-generator-expression="'HelloWorld'"/>
</beans>
Как видите, задействованы всего три элемента интеграции:
-
<twitter:search-inbound-channel-adapter>
. Входящий адаптер, который ищет твиты с "#HelloWorld" в тексте. Он инициализируетTwitterTemplate
из Spring Social для выполнения соответствующего поиска. В данной конфигурации он настроен на опрос каждые 5 секунд. Любые соответсвующие твиты будут помещены в канал с названием "tweets" (в соответствии с ID адаптера) -
<int:transformer>
. Трансформирование твитов в канале "tweets" состоит в извлечении автора(payload.fromUser
), текста(payload.text
) и объединение их в читаемуюString
. Затем она записывается в исходящий канал "files" -
<file:outbound-channel-adapter>
. Исходящий адаптер, который записывает содержимое из канала(здесь он назван "files") в файл. В данной конфигурации он настроен на добавление чего-либо из канала "files" в файл/tmp/si/HelloWorld
Пример потока иллюстрирован ниже:
Интеграционный план ссылается на два бины, которые не описаны в integration.xml
:
бин "twitterTemplate", который введен во входящий адаптер поиска и бин "newline", бин в
трансформере. Эти бины будут описаны отдельно от JavaConfig как часть главного класса
приложения.
Создание приложения исполняемым
Несмотря на то, что это обобщенная конфигурация Spring Integration плана для больших приложений, а возможно даже и для web-приложения, нет никаких причин не описывать её для простых самостоятельных приложений. Поэтому далее вы создаете главный класс, который запускает интеграционный план, а также инициализирует для его поддержки несколько бинов. Вы также можете собрать приложение в отдельный исполняемый JAR файл.
src/main/java/hello/Application.java
package hello;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.core.env.Environment;
import org.springframework.social.oauth2.OAuth2Operations;
import org.springframework.social.oauth2.OAuth2Template;
import org.springframework.social.twitter.api.Twitter;
import org.springframework.social.twitter.api.impl.TwitterTemplate;
@Configuration
@ImportResource("/hello/integration.xml")
public class Application {
public static void main(String[] args) {
new AnnotationConfigApplicationContext(Application.class);
}
@Bean
public String newline() {
return System.getProperty("line.separator");
}
@Bean
public Twitter twitterTemplate(OAuth2Operations oauth2) {
return new TwitterTemplate(oauth2.authenticateClient().getAccessToken());
}
@Bean
public OAuth2Operations oauth2Template(Environment env) {
return new OAuth2Template(env.getProperty("clientId"), env.getProperty("clientSecret"), "", "https://api.twitter.com/oauth2/token");
}
}
Как видите, этот класс предоставляет метод main()
, который загружает
контекст приложения Spring. Он также содержит аннотацию @Configuration
,
которая означает, что класс содержит определения бинов.
В частности, создаются три бина:
-
Метод
newLine()
создает простойString
бин, который содержит системный символ(ы) переноса строки. Он используется в плане интеграции в конце новой строки трансформированного твита. -
Метод
twitterTemplate()
объявляетTwitterTemplate
бин, который инициализируется в<twitter:search-inbound-channel-adapter>
-
Метод
oauth2Template()
объявляет Spring SocialOAuth2Template
бин, используемый для получения клиентского ключа доступа, когда создается предыдущий бин.
Метод oauth2Template()
содержит аргумент типа Environment
для получения
"clientId" и "clientSecret" свойств. Значения этих свойств вы получали, когда
регистрировали приложение в Twitter.
Получение их из Environment
означает, что вы не "зашили" их в этот класс конфигурации.
Однако они вам понадобятся, когда вы будете запускать приложение.
И наконец, обратите внимание, что Application
настроен с @ImportResource
для импорта интеграционного плана, описаном в /hello/integration.xml
.
Сборка исполняемого JAR
Вы можете собрать единый исполняемый JAR-файл, который содержит все необходимые зависимости, классы и ресурсы. Это делает его легким в загрузке, версионировании и развертывании сервиса как приложения на протяжении всего периода разработки, на различных средах и так далее.
./gradlew build
Затем вы можете запустить JAR-файл:
java -jar build/libs/gs-integration-0.1.0.jar
Если вы используете Maven, вы можете запустить приложение, используя mvn spring-boot:run
,
либо вы можете собрать приложение с mvn clean package
и запустить JAR примерно так:
java -jar target/gs-integration-0.1.0.jar
Если вы используете Gradle, вы можете запустить ваш сервис из командной строки:
./gradlew clean build && java -jar build/libs/gs-integration-0.1.0.jar
mvn clean package && java -jar target/gs-integration-0.1.0.jar
.
Как вариант, вы можете запустить ваш сервис напрямую из Gradle примерно так:
./gradlew bootRun
mvn spring-boot:run
.Запуск приложения
Теперь вы можете запустить ваше приложение из jar:
java -DclientId={YOUR CLIENT ID} -DclientSecret={YOUR CLIENT SECRET} -jar build/libs/{project_id}-0.1.0.jar ... app starts up ...
Убедитесь, что вы указали ваши ID приложения и секретное слово в команде, как указано выше.
Как только приложение запустится, оно соединится с Twitter и начнет собирать
твиты, которые соответствуют критерию поиска по "#HelloWorld". Приложение
обрабатывает найденные твиты через план интеграции, добавляя автора твита и
текст в файл /tmp/si/HelloWorld
.
После того, как приложение проработает некоторое время, вы можете просмотреть
файл /tmp/si/HelloWorld
и увидеть информацию о нескольких твитах.
На операционных системах UNIX можно воспользоваться командой tail
,
чтобы увидеть результаты, которые будут найдены.
tail -f /tmp/si/HelloWorld
Вы должны увидеть примерно следующее:
BrittLieTjauw : Now that I'm all caught up on the bachelorette I can leave my room #helloworld mishra_ravish : Finally, integrated #eclim. #Android #HelloWorld NordstrmPetite : Pink and fluffy #chihuahua #hahalol #boo #helloworld http://t.co/lelHhFN3gq GRhoderick : Ok Saint Louis, show me what you got. #HelloWorld
Итог
Поздравляем! Вы только что разработали простое приложение, которое использует Spring Integration для сбора твитов из Twitter, обрабатывает, а потом записывает их в файл.
С оригинальным текстом урока вы можете ознакомиться на spring.io.
comments powered by Disqus