iT邦幫忙

2021 iThome 鐵人賽

DAY 27
2

今天我們要開始實作最後一個頁面了,這個頁面功能是可以顯示上市個股日成交的資訊

還記得我們在Angular視覺化套件(Day19)所引入的ZingChart嗎?

在最後的幾天我們會透過攜帶token的方式,向StockAPI請求資料,並將資料利用ZingChart呈現出來。


現在讓我們先從httpServe開始吧

還記得我們取得上市個股日是用get方法嗎?
因此我們要新增一個get方法


import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { APIReturnObject } from '../model/APIReturnObject';
import { Observable } from 'rxjs';
import { HttpHeaders } from '@angular/common/http';
@Injectable({
  providedIn: 'root'
})
export class HttpService {
  private rootUrl = 'http://localhost:8080/';
  constructor(private http: HttpClient) { }

  getPosts(params: object, webUrl: string): Observable<APIReturnObject> {
    const headers = new HttpHeaders({
      'Content-Type': 'application/json',
      'responseType': 'json'
    });
    const options = {
      headers
    };
    return this.http.post<APIReturnObject>(this.rootUrl + webUrl, params, options);
  }

#新增get方法
  getGets(token: string, webUrl: string): Observable<APIReturnObject> {
    const headers = new HttpHeaders({
      'Content-Type': 'application/json',
      'responseType': 'json',
      'Authorization': 'Bearer ' + token
    });
    return this.http.get<APIReturnObject>(this.rootUrl + webUrl,{headers:headers});
  }
}

在這邊可以看到我們把token放置在header的Authorization屬性內


2021/10/13更新
新增一個 DailyTranctionStockData 的介面


export class DailyTranctionStockData {
    Code: string;
    Name: string;
    TradeVolume: number;
    TradeValue: number;
    OpeningPrice: number;
    HighestPrice: number;
    LowestPrice: number;
    ClosingPrice: number;
    Change: number;
    Transaction: number;
    constructor(
        Code: string,
        Name: string,
        TradeVolume: number,
        TradeValue: number,
        OpeningPrice: number,
        HighestPrice: number,
        LowestPrice: number,
        ClosingPrice: number,
        Change: number,
        Transaction: number
    ) {
        this.Code = Code;
        this.Name = Name;
        this.TradeVolume = TradeVolume;
        this.TradeValue = TradeValue;
        this.OpeningPrice = OpeningPrice;
        this.HighestPrice = HighestPrice;
        this.LowestPrice = LowestPrice;
        this.ClosingPrice = ClosingPrice;
        this.Change = Change;
        this.Transaction = Transaction;
    }

}


接下來我們要修改一下之前我們login.component儲存進sessionStorage的值


import { Component, OnInit } from '@angular/core';
import { FormControl, Validators } from '@angular/forms';
import { HttpService } from '../service/http.service';
import { Router } from '@angular/router';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
  title = '登入';
  account = new FormControl('', [Validators.required, Validators.maxLength(10)]); // 驗證字數須大於10個字
  password = new FormControl('', [Validators.required, Validators.minLength(3)]); // 驗證字數須不少於3個字
  posts: any;
  params: any;
  token: any;
  constructor(
    private httpService: HttpService,
    private router: Router,
  ) {

  }

  ngOnInit(): void {

  }

  doLogin(): void {
    this.params = {
      'account': this.account.value,
      'password': this.password.value
    }
    this.httpService.getPosts(this.params, 'user/login').subscribe(
      (response) => {
        this.posts = response;
        const data: Map<string, object> = new Map(Object.entries(response.data));
        if (data.get('token')) {
          this.token = JSON.stringify(data.get('token'));
          this.token = this.token.replace('"', ''); #把"去除掉
          sessionStorage.setItem('token', this.token);
          this.router.navigate(['index']);
        }
      },
      (error) => { console.log(error); });
  }
}

接著我們在daily-tranction-stock.component新增一個取值的方法


import { Component, OnInit } from '@angular/core';
import { HttpService } from '../service/http.service';
import { DailyTranctionStockData } from '../model/DailyTranctionStockData';

@Component({
  selector: 'app-daily-tranction-stock',
  templateUrl: './daily-tranction-stock.component.html',
  styleUrls: ['./daily-tranction-stock.component.css']
})
export class DailyTranctionStockComponent implements OnInit {
  gets: any;
  dailyTranctionStockDatas: DailyTranctionStockData[] = [];
  token = sessionStorage.getItem('token') || '';
 
  constructor(
    private httpService: HttpService
  ) { }

  ngOnInit(): void {
	#一載入頁面就發送請求
    this.httpService.getGets(this.token, 'stock/search/exchange/getStockDayAll').subscribe(
      (response) => {
        this.gets = response;
        const data: Map<string, any> = new Map(Object.entries(response.data));
        this.dailyTranctionStockDatas = data.get('dailyTranctionStockDatas');
        console.log(this.dailyTranctionStockDatas) #印出值來看
      }
    )
  }

}

實際操作後的結果

https://ithelp.ithome.com.tw/upload/images/20211012/20138857CEdC0VD8qy.png


同場加碼

之前AccessCrossOrigin的問題,我後來有發現一個比較好的設定方法
在每個Controller上面新增


@CrossOrigin("*")
public class UserController {

在SecurityConfig加上設定


@Override
    protected void configure(HttpSecurity http) throws Exception {
    	http
    		.authorizeRequests()
    		.antMatchers("/user/create").hasAuthority("ADMIN") //管理員可以新增使用者資料
    		.antMatchers("/user/login").permitAll()
    		.antMatchers("/user/search/**").hasAnyAuthority("ADMIN","NORMAL") //取得用戶資料
    		.antMatchers("/stock/search/**").hasAnyAuthority("ADMIN","NORMAL") //取得股市資料
    		.and()
    		.addFilterBefore(jWTCheckFilter, UsernamePasswordAuthenticationFilter.class)
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
    		.and()
    		.csrf().disable()
    		.cors();
    }

這樣就可以避免Access-Control-Allow-Origin的問題了

那今天先到這裡,明天繼續囉~!

參考資料
使用 HTTP 與後端服務進行通訊


上一篇
Angular Stock首頁(Day26)
下一篇
Angular Stock上市個股日成交(二)(Day28)
系列文
Angular+Spring Boot API 處理股市資料32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言