在Angular使用HttpClient
呼叫Spring Boot RESTful API取得資料。
環境:
- Windows 64 Bit
- 前端
- Angular 7
- 後端
- Java 11
- Spring Boot 2.2.4.RELEASE
後端 Spring Boot 設定
建立Spring Boot專案。參考以下:
Spring Boot的application.properties
不設定任何參數。所以預設應用程式路徑為http://localhost:8080/
。
建立類別HelloDto
。此類別作為回傳給前端的資料。
HelloDto
package com.abc.demo.dto;
public class HelloDto {
private String message;
public HelloDto(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
建立DemoController
。提供RESTful API接點。
類別名稱前必須掛上@CrossOrigin(origins = "http://localhost:4200")
,origins
值為前端Angular的domain,這樣才能接受前端Angular的跨來源資源共享(CORS)請求。
DemoController
package com.abc.demo.controller;
import com.abc.demo.dto.HelloDto;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@CrossOrigin(origins = "http://localhost:4200")
@RestController
public class DemoController {
@GetMapping(value = "/hello")
public HelloDto getHello() {
return new HelloDto("Hello! This is from Spring Boot RESTful API!"); // <--這邊的字串最後會顯示在前端頁面
}
}
呼叫http://localhost:8080/hello
時,Response回傳結果如下。
{"message": "Hello! This is from Spring Boot RESTful API!"}
Spring Boot專案../src/main
目錄結構如下:
../src/main
├─java
│ └─com
│ └─abc
│ └─demo
│ ├─DemoApplication.java
│ │
│ ├─bean
│ │ └─HelloWorldBean.java
│ │
│ ├─controller
│ │ └─DemoController.java
│ │
│ └─dto
│ └─HelloDto.java
│
└─resources
├─application.properties
├─static
└─templates
在Chrome瀏覽器位址直接輸入http://localhost:8080/hello
測試結果。
前端 Angular 設定
建立Angular專案,參考「Angular 使用Angular CLI建立一個angular專案」。
建立HelloComponent
,參考「Angular 使用Angular CLI建立Component元件」。
建立ApiService
,參考「Angular 使用Angular CLI建立Service」。
在src/app
下新增data
目錄,並建立hello-data.ts
(HelloData
)。
HelloData (hello-data.ts)
export class HelloData {
message: string;
}
此類別將設為HttpClient.get<T>()
的資料型態,對映後端回傳的json結果。
Angular可利用內建的HttpClient
呼叫API,使用前需在AppModule
(app.module.ts
)引入,要放在BrowserModule
後面。
AppModule (app.module.ts)
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http' // 引入HttpClientModule
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HelloComponent } from './hello/hello.component';
@NgModule({
declarations: [
AppComponent,
HelloComponent
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule // 引入HttpClientModule,放在BrowserModule後面
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
修改app.component.html
如下,直接顯示HelloComponent
的hello.component.html
頁面內容。
<app-hello></app-hello> <!-- 顯示HelloComponent -->
<router-outlet></router-outlet>
修改ApiService
(app.module.ts
)內容如下,負責向後端Spring Boot發出請求。
ApiService (api.service.ts)
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http'; // 引入HttpClient
import { HelloData } from '../data/hello-data'; // 引入HelloData
@Injectable({
providedIn: 'root'
})
export class ApiService {
// 注入HttpClient
constructor(
private http: HttpClient
) { }
/** 從後端取得資料 */
getHello() {
// get回傳Observable<HelloData>物件
return this.http.get<HelloData>('http://localhost:8080/hello'); // 呼叫Spring Boot的DemoController.getHello()
}
}
HttpClient.get<T>()
執行當下並不會送出請求,必須呼叫其回傳物件Observable<T>
的subscribe()
才會送出請求。
修改HelloComponent
(hello.component.ts
)內容如下,委託ApiService.getHello()
取得Observable<T>
並呼叫subscribe()
送出請求來取得後端回傳的結果。
HelloComponent (hello.component.ts)
import { Component, OnInit } from '@angular/core';
import { ApiService } from '../service/api.service'; // 引入ApiService
import { HelloData } from '../data/hello-data'; // 引入HelloData
@Component({
selector: 'app-hello',
templateUrl: './hello.component.html',
styleUrls: ['./hello.component.css']
})
export class HelloComponent implements OnInit {
hello: string; // 對映hello.component.html頁面的{{hello}}
// 注入ApiService
constructor(
private apiService: ApiService
) { }
ngOnInit() {
}
/** 委託ApiService.getHello()取得內容 */
getHello() {
this.apiService.getHello().subscribe(
value => this.success(value)
);
}
/** API呼叫成功的處理 */
success(value: HelloData) {
this.hello = value.message;
}
/** 清除頁面{{hello}}內容 */
clear() {
this.hello = '';
}
}
修改hello.component.html
如下。
hello.component.html
<div>
<button (click)="getHello()">Get Hello</button> <!-- 取得{{hello}}顯示的內容-->
<button (click)="clear()">Clear</button> <!-- 清除{{hello}}顯示的內容 -->
</div>
<hr>
<h1>{{hello}}</h1>
Get Hello及Clear按鈕利用事件綁定分別呼叫HelloComponent
的getHello()
與clear()
來更改插值符{{hello}}
的顯示內容。
Angular專案../src/app
目錄結構如下:
../src/app
├─app-routing.module.ts
├─app.component.css
├─app.component.html
├─app.component.spec.ts
├─app.component.ts
├─app.module.ts
│
├─data
│ └─hello-data.ts
│
├─hello
│ ├─hello.component.css
│ ├─hello.component.html
│ ├─hello.component.spec.ts
│ └─hello.component.ts
│
└─service
├─api.service.spec.ts
└─api.service.ts
測試
完成以上後端Spring Boot及前端Angular的設定後啟動兩個專案。
啟動後在瀏覽器輸入前端Angular的應用程式路徑http://localhost:4200/
顯示如下。
點擊按鈕效果如下。
沒有留言:
張貼留言