以前、Java EE8のJAX-RSを使ってHTTP GETとPOSTの例を紹介しました。HTTP POSTの例では、Postmanを使って動作確認をしましたが、フルスタックエンジニアはフロントエンドを作って確認したいところですよね。ここでは、以前作ったJAX-RSのHTTP POSTのバックエンドに対してAngularで作ったフロントエンドで導通確認をしてみます。

Angularでフロントエンドを構築

ここでフロントエンドをAngular (AngularJSではなく、Angular.ioのほう)を使います。私がTypeScriptを始めるきっかけとなったのは、このAngularでした。これまでAngularJSでフロントエンドを作ってきたのですが、やはり新しい開発が行われなくなったので、Angular.ioに移行することにしました。いくらTypeScriptがJavaScriptと互換性があるとはいえ、自由過ぎたJavaScriptからガチガチのTypeScriptに馴染むまでは、ちょっと時間が掛かりましたね。ただ、ITやプログラミングの世界は変化が速いので、機会を作ってキャッチアップしていく姿勢が大事だと思っています。

Angularプロジェクトを作成

さて、Angular CLIで新しいプロジェクトを作成します。

ng new myAngularFrontAppCode language: DOS .bat (dos)

数分掛かりますが、Angularのプロジェクトが作成されます。

ng newでAngularプロジェクトの作成

Angular-Materialとbootstrapの追加

必須ではないですが、少しでも見た目をキレイにするため、マテリアルデザインのためのAngular-Materialとグリッド表示が簡単に定義できるBootstrapを追加します。

ng add @angular/material
ng add @ng-bootstrap/ng-bootstrapCode language: DOS .bat (dos)

入力フィールドとボタンを配置

次に入力フィールドとボタンを作ります。Bootstrapでグリッドレイアウトを作り、Angular-Materialで要素を作っていきます。

app.component.html

<div class="container">
    <div class="row">
        <form class="mt-4 example-form">
            <mat-form-field class="example-full-width">
                <mat-label>Input1</mat-label>
                <input matInput placeholder="Input1" type="number" [(ngModel)]="input1" [name]="input1">
            </mat-form-field>
            <button type="submit" mat-raised-button color="primary" (click)="pushFcn()" class="mx-2">Post</button>
        </form>
    </div>
    <div class="row mt-2">Result: {{result}}</div>
</div>Code language: HTML, XML (xml)

mat-inputなどを使っているので、app.module.tsも編集しておきます。

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HttpClientModule } from '@angular/common/http';

import { MatInputModule } from '@angular/material/input';
import { MatButtonModule } from '@angular/material/button';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    FormsModule,
    HttpClientModule,
    MatInputModule,
    MatButtonModule,
    NgbModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
Code language: TypeScript (typescript)

mat-inputの変数はTypeScriptでの変数とバインドしています。

app.component.ts

import { Component } from '@angular/core';
import { HttpClientModule} from '@angular/common/http';
import { RestService } from './rest.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  constructor(private http: HttpClientModule, private restService: RestService) { }
  title = 'myAngularFrontApp';
  input1 = 2;
  result = null;
  
  pushFcn() {
    console.log('pushFcn started');
 };
}
Code language: TypeScript (typescript)

Angularのサービスを追加

RESTを呼び出すために、HTTP POSTをするサービスを追加します。本当は一つのTypeScriptファイルの中に含めたかったのですが、Angularの公式Getting StartedのHeroの例でもサービスを使っているので、ここでもそれに倣います。ここではrestという名前のサービスにします。

ng generate service restCode language: DOS .bat (dos)
ng generateでサービスを作成

これによって作成されたrest.service.tsを編集します。18行目で以前作ったJava EEのRESTのエンドポイントにHTTP POSTしています。

rest.service.ts

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { HttpClient, HttpHeaders } from '@angular/common/http';

const httpOptions = {
    headers: new HttpHeaders({
        'Content-Type': 'application/json',
        'Accept': 'application/json'        
    })
};

@Injectable({
  providedIn: 'root'
})
export class RestService {
  constructor(private httpClient: HttpClient) { }
  postTest(postParam: any): Observable<any>{
      return this.httpClient.post('/mavenproject1/rest/returnInput', postParam, httpOptions);      
  }
}
Code language: TypeScript (typescript)

ボタンプッシュの関数を修正

それでは先ほどのpushFcnをこのRESTサービスを呼び出すように修正します。

app.component.ts

pushFcn() {
    console.log('pushFcn started');
    let postParam = {
        input1: this.input1
    };
    this.restService.postTest(postParam).subscribe((data: Number) => {
        this.result = data;
    });
  };
Code language: TypeScript (typescript)

subscribeを使うことで、HTTP POSTの結果を変数に割り当てられます。

Javaバックエンドのwebappを差し替え

さて、このままAngularでng serveをして動作確認をしても良いのですが、どうせ最後はバックエンドにHTMLを置くので、ビルドしてから動作確認をします。フロントエンドとバックエンドで同じポート番号で通信するようになればCORSの問題も悩まなくて済みますし。

ng build --base-href /mavenproject1/Code language: DOS .bat (dos)

ここでbase-hrefを付けているのは、バックエンドのJavaがlocalhost:8080/mavenproject1で動いているためです。

ビルドがうまくいくと、distフォルダにAngularプロジェクト名のフォルダが作成され、index.htmlやruntime.jsなどのファイル一式が置かれます。

これらのファイルをJavaのwebappフォルダにコピー&ペーストします。

Angularのdistフォルダからwebappフォルダにコピペ

導通確認

NetBeansからmaven runを実行した後、Webブラウザで開いて、動作確認をしてみましょう。

Webブラウザでhttp://localhost:8080/mavenproject1にアクセスします。

input1の入力フィールドに数字を入れて、Postボタンをクリックすると、バックエンドに値がHTTP POSTされ、サーバーから入力したものと同じ値がリターンされます。ChromeのNetworkタブからサーバーからのResponseが確認できます。これで導通確認も問題なしですね。

ブラウザを開いて実際にバックエンドにPOSTしてみましょう
ブラウザから数字を入力して、バックエンドにPOSTしてみましょう

Postmanでの導通確認も良いのですが、フロントエンドから動くことを確認できて、よりWebアプリケーションのイメージが付くようになりましたね。

Categories:

No responses yet

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です