使用 RxJs 和 Angular 5 来处理来自 Spring Boot 的服务器发送事件
Using RxJs and Angular 5 in order to deal with server-sent events from Spring Boot
我需要根据 MySQL 发出的数据更新我的 Angular UI Spring MYSQL 数据库中发生的每个更新.但是在 Angular 端,我无法获取数据。
这是我的 WebController.java Spring 启动:
@GetMapping("/summary")
public SseEmitter Summary(@RequestParam Map<String,String> queryParam,String date, String target) {
Connection conn = null;
List<Map<String, Object>> listOfMaps = null;
Statement stmt = null;
prodDate = queryParam.get("date").replaceAll("\'", "");
prodTarget = queryParam.get("target").replaceAll("\'", "");
final SseEmitter emitter = new SseEmitter();
try{
Class.forName("com.mysql.jdbc.Driver");
System.out.println("Connecting to database...To retrive SUMMARY");
conn = DriverManager.getConnection(DB_URL,USER,PASS);
String query= "SELECT migration_states.state END AS state, migrations.mignum, migrations.projectleader, migrations.productiondate, migrations.installationtiers, "
+ "migrations.targetplatform, migrations.apprelated, migrations.appversion "
+ "FROM (migrations LEFT JOIN migration_states ON migrations.state = migration_states.state_code) "
+ "WHERE migrations.productiondate=? AND migrations.targetplatform=? AND migration_states.state NOT LIKE '%Cancelled%' ";
QueryRunner queryRunner = new QueryRunner();
listOfMaps = queryRunner.query(conn, query, new MapListHandler(), prodDate, prodTarget);
emitter.send(listOfMaps,MediaType.APPLICATION_JSON);
System.out.println(emitter);
conn.close();
}
catch (SQLException se) {
se.printStackTrace();
emitter.completeWithError(se);
return emitter;
}catch(Exception e){
e.printStackTrace();
emitter.completeWithError(e);
return emitter;
}finally {
DbUtils.closeQuietly(conn);
}
emitter.complete();
return emitter;
}
当在 Postman
中触发时,这给了我以下结果
http://localhost:8080/api/summary?date=2018-06-06&target=Production
data:[{"state":"Completed","mignum":146289,"projectleader":"Eric Lok","productiondate":"2018-06-06","installationtiers":"Windows Server","targetplatform":"Production","apprelated":"UPS Pickup Point Web Application","appversion":"2.25"},
{"state":"Completed","mignum":146381,"projectleader":"James Rice","productiondate":"2018-06-06","installationtiers":"Linux Web WL10","targetplatform":"Production","apprelated":"Content Only","appversion":""},
{"state":"Completed","mignum":146461,"projectleader":"Nishith Jani","productiondate":"2018-06-06","installationtiers":"Linux BEA WL12","targetplatform":"Production","apprelated":"Tracking Comp","appversion":"1801.20"},
{"state":"Completed","mignum":146574,"projectleader":"Nishith Jani","productiondate":"2018-06-06","installationtiers":"Linux BEA WL12","targetplatform":"Production","apprelated":"Tracking Comp","appversion":"01-00-07-17"}]
这是我的 Angular 订阅 WebController 的服务调用
import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { map } from 'rxjs/operators';
@Injectable()
export class DashboardDataService {
public baseUrl = 'http://localhost:8080/api';
public headers = new Headers({'Content-Type': 'application/json' });
public options = new RequestOptions({headers: this.headers});
constructor(private _http: Http) { }
getSummary(_date, _target) {
return this._http.get(this.baseUrl + '/summary?date='+_date+"&target="+_target, this.options).pipe(map((response: Response) => response.json()));
}
}
这是我的组件
import { Component, OnInit, OnDestroy } from '@angular/core';
import { DashboardDataService } from '../shared-service/dashboard-data.service';
@Component({
selector: 'app-dashboard-view',
templateUrl: './dashboard-view.component.html',
styleUrls: ['./dashboard-view.component.css']
})
export class DashboardViewComponent implements OnInit, OnDestroy {
constructor(private _dashboardService: DashboardDataService) { }
ngOnInit() {
this._dashboardService.getSummary(this._date, this._target).addEventListener((dashboardataa) => {
this.dashboardataa = dashboardataa;
console.log("this.dashboardata-->", this.dashboardataa);
}, (error) => { console.error('SERVER ERROR'); });
}
}
但问题是
console.log("this.dashboardata-->", this.dashboardataa);
从不打印。我是 Spring、Ssemitter 和 Rxjs 的新手,所以我在这里做错了。我无法弄清楚。
阅读一些博客说我使用 addEventListener,但是当我尝试这个
this._dashboardService.getSummary(this._date, this._target).addEventListener((dashboardataa) => {
this.dashboardataa = dashboardataa;
console.log("this.dashboardata-->", this.dashboardataa); }
我收到错误提示
error TS2339: Property 'addEventListener' does not exist on type
'Observable'.
任何人都可以帮助我如何在 Angular 端编写正确的代码,以获取 json 数据,当服务器端发生更新时,这些数据将被发出。
你应该只使用 Observables:
getSummary(_date, _target) : Observable<any> {
return this._http.get(this.baseUrl + '/summary?date='+_date+"&target="+_target,
this.options);
}
并在您的组件中订阅它:
this._dashboardService.getSummary(this._date, this._target).subscribe((dashboardataa) => {
this.dashboardataa = dashboardataa;
console.log("this.dashboardata-->", this.dashboardataa);
}, (error) => { console.error('SERVER ERROR'); });
}
}
我需要根据 MySQL 发出的数据更新我的 Angular UI Spring MYSQL 数据库中发生的每个更新.但是在 Angular 端,我无法获取数据。
这是我的 WebController.java Spring 启动:
@GetMapping("/summary")
public SseEmitter Summary(@RequestParam Map<String,String> queryParam,String date, String target) {
Connection conn = null;
List<Map<String, Object>> listOfMaps = null;
Statement stmt = null;
prodDate = queryParam.get("date").replaceAll("\'", "");
prodTarget = queryParam.get("target").replaceAll("\'", "");
final SseEmitter emitter = new SseEmitter();
try{
Class.forName("com.mysql.jdbc.Driver");
System.out.println("Connecting to database...To retrive SUMMARY");
conn = DriverManager.getConnection(DB_URL,USER,PASS);
String query= "SELECT migration_states.state END AS state, migrations.mignum, migrations.projectleader, migrations.productiondate, migrations.installationtiers, "
+ "migrations.targetplatform, migrations.apprelated, migrations.appversion "
+ "FROM (migrations LEFT JOIN migration_states ON migrations.state = migration_states.state_code) "
+ "WHERE migrations.productiondate=? AND migrations.targetplatform=? AND migration_states.state NOT LIKE '%Cancelled%' ";
QueryRunner queryRunner = new QueryRunner();
listOfMaps = queryRunner.query(conn, query, new MapListHandler(), prodDate, prodTarget);
emitter.send(listOfMaps,MediaType.APPLICATION_JSON);
System.out.println(emitter);
conn.close();
}
catch (SQLException se) {
se.printStackTrace();
emitter.completeWithError(se);
return emitter;
}catch(Exception e){
e.printStackTrace();
emitter.completeWithError(e);
return emitter;
}finally {
DbUtils.closeQuietly(conn);
}
emitter.complete();
return emitter;
}
当在 Postman
中触发时,这给了我以下结果http://localhost:8080/api/summary?date=2018-06-06&target=Production
data:[{"state":"Completed","mignum":146289,"projectleader":"Eric Lok","productiondate":"2018-06-06","installationtiers":"Windows Server","targetplatform":"Production","apprelated":"UPS Pickup Point Web Application","appversion":"2.25"},
{"state":"Completed","mignum":146381,"projectleader":"James Rice","productiondate":"2018-06-06","installationtiers":"Linux Web WL10","targetplatform":"Production","apprelated":"Content Only","appversion":""},
{"state":"Completed","mignum":146461,"projectleader":"Nishith Jani","productiondate":"2018-06-06","installationtiers":"Linux BEA WL12","targetplatform":"Production","apprelated":"Tracking Comp","appversion":"1801.20"},
{"state":"Completed","mignum":146574,"projectleader":"Nishith Jani","productiondate":"2018-06-06","installationtiers":"Linux BEA WL12","targetplatform":"Production","apprelated":"Tracking Comp","appversion":"01-00-07-17"}]
这是我的 Angular 订阅 WebController 的服务调用
import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { map } from 'rxjs/operators';
@Injectable()
export class DashboardDataService {
public baseUrl = 'http://localhost:8080/api';
public headers = new Headers({'Content-Type': 'application/json' });
public options = new RequestOptions({headers: this.headers});
constructor(private _http: Http) { }
getSummary(_date, _target) {
return this._http.get(this.baseUrl + '/summary?date='+_date+"&target="+_target, this.options).pipe(map((response: Response) => response.json()));
}
}
这是我的组件
import { Component, OnInit, OnDestroy } from '@angular/core';
import { DashboardDataService } from '../shared-service/dashboard-data.service';
@Component({
selector: 'app-dashboard-view',
templateUrl: './dashboard-view.component.html',
styleUrls: ['./dashboard-view.component.css']
})
export class DashboardViewComponent implements OnInit, OnDestroy {
constructor(private _dashboardService: DashboardDataService) { }
ngOnInit() {
this._dashboardService.getSummary(this._date, this._target).addEventListener((dashboardataa) => {
this.dashboardataa = dashboardataa;
console.log("this.dashboardata-->", this.dashboardataa);
}, (error) => { console.error('SERVER ERROR'); });
}
}
但问题是
console.log("this.dashboardata-->", this.dashboardataa);
从不打印。我是 Spring、Ssemitter 和 Rxjs 的新手,所以我在这里做错了。我无法弄清楚。 阅读一些博客说我使用 addEventListener,但是当我尝试这个
this._dashboardService.getSummary(this._date, this._target).addEventListener((dashboardataa) => {
this.dashboardataa = dashboardataa;
console.log("this.dashboardata-->", this.dashboardataa); }
我收到错误提示
error TS2339: Property 'addEventListener' does not exist on type 'Observable'.
任何人都可以帮助我如何在 Angular 端编写正确的代码,以获取 json 数据,当服务器端发生更新时,这些数据将被发出。
你应该只使用 Observables:
getSummary(_date, _target) : Observable<any> {
return this._http.get(this.baseUrl + '/summary?date='+_date+"&target="+_target,
this.options);
}
并在您的组件中订阅它:
this._dashboardService.getSummary(this._date, this._target).subscribe((dashboardataa) => {
this.dashboardataa = dashboardataa;
console.log("this.dashboardata-->", this.dashboardataa);
}, (error) => { console.error('SERVER ERROR'); });
}
}