Рубрики
Без рубрики

Весеннее Облако – Добавление Углового 4

Узнайте, как создать одностраничное приложение с использованием интерфейса на основе Angular 4.

Автор оригинала: Tim Schimandle.

1. Обзор

В нашей последней статье о весеннем облаке мы добавили поддержку Zipkin в наше приложение. В этой статье мы собираемся добавить интерфейсное приложение в наш стек.

До сих пор мы полностью работали над бэкэндом для создания нашего облачного приложения. Но что хорошего в веб-приложении, если в нем нет пользовательского интерфейса? В этой статье мы собираемся решить эту проблему, интегрировав одностраничное приложение в наш проект.

Мы будем писать это приложение, используя Angular и Bootstrap . Стиль кода Angular 4 очень похож на кодирование приложения Spring, которое является естественным переходом для разработчика Spring! Хотя в интерфейсном коде будет использоваться Angular, содержание этой статьи можно легко распространить на любую интерфейсную платформу с минимальными усилиями.

В этой статье мы собираемся создать приложение Angular 4 и подключить его к нашим облачным сервисам. Мы продемонстрируем, как интегрировать вход в систему между SPA и Spring Security. Мы также покажем, как получить доступ к данным нашего приложения, используя поддержку Angular для HTTP-связи.

2. Изменения Шлюза

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

2.1. Обновление безопасности Http

Во-первых, давайте обновим настроим(http HttpSecurity) метод в нашем шлюзе SecurityConfig.java класс:

@Override
protected void configure(HttpSecurity http) {
    http
      .formLogin()
      .defaultSuccessUrl("/home/index.html", true)
      .and()
    .authorizeRequests()
      .antMatchers("/book-service/**", "/rating-service/**", "/login*", "/")
      .permitAll()
      .antMatchers("/eureka/**").hasRole("ADMIN")
      .anyRequest().authenticated()
      .and()
    .logout()
      .and()
    .csrf().disable();
}

Во-первых, мы добавляем URL-адрес успеха по умолчанию, чтобы указать на /home/index.html так как именно здесь будет жить наше угловое приложение. Затем мы настраиваем antmatchers, чтобы разрешить любой запрос через шлюз, за исключением ресурсов Eureka . Это делегирует все проверки безопасности внутренним службам.

Затем мы удалили URL-адрес успешного выхода, так как перенаправление по умолчанию обратно на страницу входа будет работать нормально.

2.2. Добавьте основную конечную точку

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

В проекте шлюза добавьте Контроллер аутентификации класс:

@RestController
public class AuthenticationController {
 
    @GetMapping("/me")
    public Principal getMyUser(Principal principal) {
        return principal;
    }
}

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

2.3. Добавьте целевую страницу

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

В src/основные/ресурсы/статические, давайте добавим index.html файл со ссылкой на страницу входа в систему:





    
    Book Rater Landing


    

Book Rater

So many great things about the books

Login

3. Угловой интерфейс командной строки и стартовый проект

Перед началом нового проекта Angular обязательно установите последние версии Node.js и нпм .

3.1. Установите угловой интерфейс командной строки

Для начала нам нужно будет использовать npm для загрузки и установки интерфейса командной строки Angular. Откройте терминал и запустите:

npm install -g @angular/cli

Это позволит загрузить и установить CLI по всему миру.

3.2. Установите новый проект

Все еще находясь в терминале, перейдите к проекту шлюза и перейдите в папку gateway/src/main. Создайте каталог под названием “угловой” и перейдите к нему. Отсюда беги:

ng new ui

Будьте терпеливы; CLI настраивает совершенно новый проект и загружает все зависимости JavaScript с помощью npm. Нередко этот процесс занимает много минут.

Команда ng является ярлыком для углового интерфейса командной строки, параметр new указывает этому интерфейсу командной строки создать новый проект, а команда ui дает нашему проекту имя.

3.3. Запустите проект

Как только команда new будет завершена. Перейдите в созданную папку ui и запустите:

ng serve

Как только проект будет построен, перейдите к http://localhost:4200. Мы должны увидеть это в браузере:

Поздравляю! Мы только что создали угловое приложение!

3.4. Установите Загрузчик

Давайте используем npm для установки начальной загрузки. Из каталога пользовательского интерфейса выполните эту команду:

npm install [email protected] --save

Это приведет к загрузке начальной загрузки в папку node_modules.

В каталоге ui откройте файл . angular-cli.json . Это файл, который настраивает некоторые свойства нашего проекта. Найдите свойство приложения > стили и добавьте расположение файла нашего CSS-класса начальной загрузки:

"styles": [
    "styles.css",
    "../node_modules/bootstrap/dist/css/bootstrap.min.css"
],

Это проинструктирует Angular включить начальную загрузку в скомпилированный CSS-файл, созданный вместе с проектом.

3.5. Установите выходной каталог сборки

Затем нам нужно сообщить Angular, куда поместить файлы сборки, чтобы наше приложение spring boot могло их обслуживать. Spring Boot может обслуживать файлы из двух расположений в папке ресурсов:

  • src/основные/ресурсы/статические
  • src/основной/ресурс/общедоступный

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

Снова откройте файл . angular-cli.json и найдите свойство приложения > outDir . Обновите эту строку :

"outDir": "../../resources/static/home",

Если проект Angular находится в src/main/angular/ui, он будет создан в папке src/main/resources/public. Если приложение находится в другой папке, эту строку необходимо будет изменить, чтобы правильно установить местоположение.

3.6. Автоматизируйте сборку С помощью Maven

Наконец, мы настроим автоматическую сборку для запуска при компиляции нашего кода. Эта задача ant будет запускать задачу сборки углового интерфейса командной строки всякий раз, когда выполняется “компиляция mvn”. Добавьте этот шаг к шлюзу POM.xml чтобы гарантировать, что каждый раз при компиляции мы получаем последние изменения пользовательского интерфейса:


    maven-antrun-plugin
    
        
            generate-resources
            
                
                    
                        
                        
                        
                    
                    
                        
                        
                    
                
            
            
                run
            
        
    

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

Теперь давайте начнем создавать наше угловое приложение!

4. Угловой

В этом разделе руководства мы создадим механизм аутентификации на нашей странице. Мы используем базовую аутентификацию и следуем простому потоку, чтобы заставить ее работать.

У пользователей есть форма входа в систему, в которой они могут ввести свое имя пользователя и пароль.

Затем мы используем их учетные данные для создания маркера аутентификации base64 и запрашиваем конечную точку “/me” . Конечная точка возвращает объект Принципал , содержащий роли этого пользователя.

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

Давайте посмотрим, как это делается!

4.1. Шаблон

В проекте шлюза перейдите к src/main/angular/ui/src/app и откройте app.component.html файл. Это первый шаблон, загружаемый Angular, и он будет использоваться нашими пользователями после входа в систему.

Здесь мы добавим некоторый код для отображения панели навигации с формой входа в систему:



Book Rater App

Anyone can view the books.

Users can view and create ratings

Admins can do anything!

Этот код настраивает панель навигации с классами начальной загрузки. В панель встроена встроенная форма входа. Angular использует эту разметку для динамического взаимодействия с JavaScript для визуализации различных частей страницы и управления такими вещами, как отправка формы.

Такие операторы, как , просто указывают, что при отправке формы вызовите метод “при входе в систему(f)” и передайте форму этой функции. В jumbotron div у нас есть теги абзацев, которые будут отображаться динамически в зависимости от состояния нашего основного объекта.

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

4.2. Машинописный текст

Из того же каталога откройте файл app.component.ts. В этот файл мы добавим все свойства и методы машинописи, необходимые для работы нашего шаблона:

import {Component} from "@angular/core";
import {Principal} from "./principal";
import {Response} from "@angular/http";
import {Book} from "./book";
import {HttpService} from "./http.service";

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    selectedBook: Book = null;
    principal: Principal = new Principal(false, []);
    loginFailed: boolean = false;

    constructor(private httpService: HttpService){}

    ngOnInit(): void {
        this.httpService.me()
          .subscribe((response: Response) => {
              let principalJson = response.json();
              this.principal = new Principal(principalJson.authenticated,
              principalJson.authorities);
          }, (error) => {
              console.log(error);
        });
    }

    onLogout() {
        this.httpService.logout()
          .subscribe((response: Response) => {
              if (response.status === 200) {
                  this.loginFailed = false;
                  this.principal = new Principal(false, []);
                  window.location.replace(response.url);
              }
           }, (error) => {
               console.log(error);
       });
    }
}

Этот класс подключается к методу углового жизненного цикла, ngOnInit() . В этом методе мы вызываем конечную точку /me , чтобы получить текущую роль и состояние пользователя. Это определяет, что пользователь видит на главной странице. Этот метод будет срабатывать всякий раз, когда создается этот компонент, что является отличным временем для проверки свойств пользователя на наличие разрешений в нашем приложении.

У нас также есть метод onLogout () , который выводит пользователя из системы и восстанавливает состояние этой страницы до ее первоначальных настроек.

Хотя здесь происходит какое-то волшебство. Свойство http-службы , объявленное в конструкторе. Angular вводит это свойство в наш класс во время выполнения. Angular управляет одноэлементными экземплярами классов обслуживания и внедряет их с помощью инъекции конструктора, точно так же, как Spring!

Далее нам нужно определить класс HTTPService .

4.3. HTTPService

В том же каталоге создайте файл с именем “http.service.ts” . В этот файл добавьте этот код для поддержки методов входа и выхода из системы:

import {Injectable} from "@angular/core";
import {Observable} from "rxjs";
import {Response, Http, Headers, RequestOptions} from "@angular/http";
import {Book} from "./book";
import {Rating} from "./rating";

@Injectable()
export class HttpService {

    constructor(private http: Http) { }

    me(): Observable {
        return this.http.get("/me", this.makeOptions())
    }

    logout(): Observable {
        return this.http.post("/logout", '', this.makeOptions())
    }

    private makeOptions(): RequestOptions {
        let headers = new Headers({'Content-Type': 'application/json'});
        return new RequestOptions({headers: headers});
    }
}

В этом классе мы вводим другую зависимость, используя конструкцию DI от Angular. На этот раз это класс Http . Этот класс обрабатывает все HTTP-сообщения и предоставляется нам платформой.

Каждый из этих методов выполняет HTTP-запрос с использованием HTTP-библиотеки angular. Каждый запрос также указывает тип содержимого в заголовках.

Теперь нам нужно сделать еще одну вещь, чтобы служба Http была зарегистрирована в системе внедрения зависимостей. Откройте файл app.module.ts и найдите свойство providers. Добавьте службу Http в этот массив. Результат должен выглядеть так:

providers: [HttpService],

4.4. Добавить Принципала

Далее, давайте добавим наш основной объект DTO в наш код машинописи. В том же каталоге добавьте файл с именем “principal.ts” и добавьте этот код:

export class Principal {
    public authenticated: boolean;
    public authorities: Authority[] = [];
    public credentials: any;

    constructor(authenticated: boolean, authorities: any[], credentials: any) {
        this.authenticated = authenticated;
        authorities.map(
          auth => this.authorities.push(new Authority(auth.authority)))
        this.credentials = credentials;
  }

    isAdmin() {
        return this.authorities.some(
          (auth: Authority) => auth.authority.indexOf('ADMIN') > -1)
    }
}

export class Authority {
    public authority: String;

    constructor(authority: String) {
        this.authority = authority;
    }
}

Мы добавили класс Принципал и класс Полномочия . Это два класса DTO, очень похожие на POJOs в приложении Spring. Из-за этого нам не нужно регистрировать эти классы в другой системе в angular.

Затем давайте настроим правило перенаправления для перенаправления неизвестных запросов в корневой каталог нашего приложения.

4.5. Обработка 404

Давайте вернемся к Java – коду службы шлюза. В том, где Приложение шлюза находится класс, добавьте новый класс с именем Конфигурация страницы ошибок :

@Component
public class ErrorPageConfig implements ErrorPageRegistrar {
 
    @Override
    public void registerErrorPages(ErrorPageRegistry registry) {
        registry.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND,
          "/home/index.html"));
    }

}

Этот класс идентифицирует любой ответ 404 и перенаправит пользователя на “/home/index.html” . В приложении на одной странице мы обрабатываем весь трафик, не направляемый на выделенный ресурс, поскольку клиент должен обрабатывать все доступные маршруты.

Теперь мы готовы запустить это приложение и посмотреть, что мы создали!

4.6. Сборка и просмотр

Теперь запустите ” mvn compile ” из папки шлюза. Это позволит скомпилировать наш исходный код java и создать приложение Angular в общей папке. Давайте запустим другие облачные приложения: config , discovery и zipkin . Затем запустите проект шлюза. Когда служба запустится, перейдите к http://localhost:8080 чтобы увидеть наше приложение. Мы должны увидеть что-то подобное:

Далее давайте перейдем по ссылке на страницу входа в систему:

Войдите в систему, используя учетные данные пользователя/пароля. Нажмите “Войти”, и мы должны быть перенаправлены на/home/index.html где загружается наше одностраничное приложение.

Похоже, что наш jumbotron указывает на то, что мы вошли в систему как пользователь! Теперь выйдите из системы, нажав на ссылку в правом верхнем углу, и войдите в систему, используя на этот раз учетные данные admin/admin .

Выглядит хорошо! Теперь мы вошли в систему как администратор.

5. Заключение

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

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

Если вы хотите посмотреть, как построена остальная часть сайта, как всегда, вы можете найти исходный код на Github .