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

Доступ к данным Twitter

Этот урок освещает процесс создания простого web-приложения, которое собирает данные из Twitter.

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

Вы создадите Spring приложение, которое получает данные профиля пользователя Twitter и людей, которые подписаны на этого пользователя.

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

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

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

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

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

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

Когда вы закончите, можете сравнить получившийся результат с образцом в gs-accessing-twitter/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-milestone" }
        mavenLocal()
    }
    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-accessing-twitter'
    version =  '0.1.0'
}

repositories {
    mavenCentral()
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-thymeleaf")
    compile("org.springframework.social:spring-social-twitter")
}

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

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

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

Активация Twitter

До того, как вы соберетесь получить пользовательские данные из Twitter, вы должны указать ваши ID приложения и секретное слово в свойствах spring.social.twitter.appId и spring.social.twitter.appSecret. Вы можете настроить эти свойства через любые средства, поддерживаемые Spring Boot, включая их установку в файл application.properties:

src/main/resources/application.properties

spring.social.twitter.appId={{put app ID here}}
spring.social.twitter.appSecret={{put app secret here}}

Как видите, здесь указаны фальшивые значения. Значения, передаваемые этим свойствам, соответствуют значениям ключа и секретного слова, которые вам были даны при регистрации приложения в Twitter. Чтобы код заработал, достаточно заменить значения свойств на правильные ваши значения.

Присутствие этих свойств и Spring Social Twitter в classpath приведет к автоматической настройке Spring Social ConnectController, TwitterConnectionFactory и других компонент Spring Social фреймворка.

Создание представления статуса соединения

Несмотря на то, что ConnectController многое делает, перенаправляя на Twitter и обрабатывает перенаправления из Twitter, он также отображает состояние подключения, если сделать запрос /connect. ConnectController отображает представление, соответствующее connect/{provider ID}Connect когда не существует соединения и к connect/{provider ID}Connected, когда оно доступно. В данном случае, {provider ID} является "twitter".

ConnectController не имеет собственного представления, поэтому вам необходимо создать его. Для начала, будет отображено вот это Thymeleaf представление при отсутствии соединения с Twitter:

src/main/resources/templates/connect/twitterConnect.html

<html>
	<head>
		<title>Hello Twitter</title>
	</head>
	<body>
		<h3>Connect to Twitter</h3>

		<form action="/connect/twitter" method="POST">
			<div class="formInfo">
				<p>You aren't connected to Twitter yet. Click the button to connect this application with your Twitter account.</p>
			</div>
			<p><button type="submit">Connect to Twitter</button></p>
		</form>
	</body>
</html>

Форма отобразится при POST запросе /connect/twitter, который обрабатывается ConnectController и который запускает OAuth авторизацию.

Здесь представление, которое отображается при наличии соединения:

src/main/resources/templates/connect/twitterConnected.html

<html>
	<head>
		<title>Hello Twitter</title>
	</head>
	<body>
		<h3>Connected to Twitter</h3>

		<p>
			You are now connected to your Twitter account.
			Click <a href="/">here</a> to see your Twitter friends.
		</p>
	</body>
</html>

Сбор Twitter данных

Теперь, когда Twitter настроен в вашем приложении, вы можете написать Spring MVC контроллер, который собирает данные пользователя, авторизованного в приложении и отображает его в браузере. HelloController будет являться таким контроллером:

src/main/java/hello/HelloController.java

package hello;

import javax.inject.Inject;

import org.springframework.social.connect.ConnectionRepository;
import org.springframework.social.twitter.api.CursoredList;
import org.springframework.social.twitter.api.Twitter;
import org.springframework.social.twitter.api.TwitterProfile;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/")
public class HelloController {

    private Twitter twitter;

    private ConnectionRepository connectionRepository;

    @Inject
    public HelloController(Twitter twitter, ConnectionRepository connectionRepository) {
        this.twitter = twitter;
        this.connectionRepository = connectionRepository;
    }

    @RequestMapping(method=RequestMethod.GET)
    public String helloTwitter(Model model) {
        if (connectionRepository.findPrimaryConnection(Twitter.class) == null) {
            return "redirect:/connect/twitter";
        }

        model.addAttribute(twitter.userOperations().getUserProfile());
        CursoredList<TwitterProfile> friends = twitter.friendOperations().getFriends();
        model.addAttribute("friends", friends);
        return "hello";
    }

}

HelloController сделан с конструктором, одним из параметров которого является Twitter объект. Twitter объект предоставляет доступ к Spring Social Twitter API.

Метод helloTwitter() имеет аннотацию @RequestMapping и означает, что он должен обрабатывать GET запросы для корневого адреса "/". Первое, что он делает, это проверка авторизован ли пользователь для доступа к пользовательским данным в Twitter. Если нет, то пользователь перенаправляется к ConnectController, чтобы начать процесс авторизации.

Если пользователь авторизован, то приложение может собирать любые данные, которые ему доступны. На примере данного урока приложение собирает только данные профиля пользователя, в частности, список профилей пользователей, которые подписаны на авторизованного пользователя. Они помещены в модель, которая отбражается при обращении к "hello".

Говоря о представлении "hello", возьмем такой Thymeleaf шаблон:

src/main/resources/templates/hello.html

<html>
	<head>
		<title>Hello Twitter</title>
	</head>
	<body>
		<h3>Hello, <span th:text="${twitterProfile.name}">Some User</span>!</h3>

		<h4>These are your friends:</h4>

		<ul>
			<li th:each="friend:${friends}" th:text="${friend.name}">Friend</li>
		</ul>
	</body>
</html>

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

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

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

src/main/java/hello/Application.java

package hello;

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

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {

    /*
     * SPRING BOOTSTRAP MAIN
     */
    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 не нужен! Автоконфигурация полезный и гибкий механизм. Подробную информацию смотрите в API документации.

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

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

./gradlew build

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

java -jar build/libs/gs-accessing-twitter-0.1.0.jar

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

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

Когда приложение запустится, откройте в браузере адрес http://localhost:8080. Т.к. подключение пока не существует, вы увидите экран с предложением вам создать соединение с Twitter:

Когда вы нажмете Connect to Twitter, браузер перенаправит вас на страницу авторизации:

На данном этапе Twitter спросит вас разрешение приложению читать твиты вашего профиля и тех, кто на вас подписан. Эта страница введет вас в заблуждение, т.к. приложение в данном случае будет только читать информацию вашего профиля и профилей ваших друзей. Нажмите на Authorize app для получения разрешения.

Получив разрешение, Twitter перенаправит к приложению. Соединение создано и сохранено в репозитории соединения. Вы должны увидеть эту страницу, означающую, что соединение установлено:

Если вы нажмете на ссылку на странице статуса соединения, вы перейдете на главную страницу. На этот раз, когда соединение существует, вы увидите ваше имя в Twitter и список ваших друзей:

Итог

Поздравляем! Вы только что разработали простое web-приложение, используя Spring Social для получения данных своего профиля в Twitter и профилей своих друзей.

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

comments powered by Disqus