回文集目录:JHipster一知半解
block并非一个子模块,所以并没有index.ts,里面放了系统的一些配置信息、拦截器。
config子目录
prod.config.ts启动时候用的配置,根据传入的DEBUG_INFO_ENABLED决定是否启动生产模式。(DEBUG_INFO_ENABLED实际是根据用的dev还是prod的webpack文件判断的)
uib-pagination.config.ts用来构造通用的PaginationConfig分页配置,可根据工程实际使用情况修改
inteceptor子目录(划重点,JHipster的拦截器实现)
- auth-expired.interceptor.ts
responseIntercept(observable: Observable<Response>): Observable<Response> {
return <Observable<Response>> observable.catch((error, source) => {
if (error.status === 401) {
const loginService: LoginService = this.injector.get(LoginService);
loginService.logout();
}
return Observable.throw(error);
});
}
仅拦截Response,实现任何通讯请求,只要服务器返回了401,就执行登出操作。
- auth.interceptor.ts
requestIntercept(options?: RequestOptionsArgs): RequestOptionsArgs {
//判断一下是否是向SERVER_API_URL的请求,如果是测试test的就不拦截
if (!options || !options.url || (/^http/.test(options.url) && !(SERVER_API_URL && options.url.startsWith(SERVER_API_URL)))) {
return options;
}
//从localStorage和sessionStorage两个地方取出认证Token,并加上'Bearer '放到请求头中。
const token = this.localStorage.retrieve('authenticationToken') || this.sessionStorage.retrieve('authenticationToken');
if (!!token) {
options.headers.append('Authorization', 'Bearer ' + token);
}
return options;
}
仅拦截请求Request,这里用Jhipster推荐的JWT方式存储会话认证信息。'Bearer '这个是魔数,前后端都按照这个方式设置和读取。
参见\security\jwtJWTFilter.java。
(HttpSession)方式,代码?
- errorhandler.interceptor.ts
responseIntercept(observable: Observable<Response>): Observable<Response> {
return <Observable<Response>> observable.catch((error) => {
//401未授权错误,无响应说明text,路径为/api/account用户操作。
if (!(error.status === 401 && (error.text() === '' ||
(error.json().path && error.json().path.indexOf('/api/account') === 0 )))) {
if (this.eventManager !== undefined) {
this.eventManager.broadcast( {name: 'jhipsterSampleApplicationNg2App.httpError', content: error});
}
}
return Observable.throw(error);
});
}
仅拦截响应Response,针对3种错误,才使用eventManager广播httpError。JhiAlertErrorComponent会接收这个错误,提示一个错误Alert给用户。
- notification.interceptor.ts
responseIntercept(observable: Observable<Response>): Observable<Response> {
return observable.map((response: Response) => {
const headers = [];
//取出app-alert,app-params的head信息。
response.headers.forEach((value, name) => {
if (name.toLowerCase().endsWith('app-alert') || name.toLowerCase().endsWith('app-params')) {
headers.push(name);
}
});
//使用alertService显示成功信息
if (headers.length > 1) {
headers.sort();
const alertKey = response.headers.get(headers[ 0 ]);
if (typeof alertKey === 'string') {
if (this.alertService) {
const alertParam = headers.length >= 2 ? response.headers.get(headers[ 1 ]) : null;
this.alertService.success(alertKey, { param : alertParam }, null);
}
}
}
return response;
}).catch((error) => {
return Observable.throw(error); // here, response is an error
});
}
仅拦截响应Response,遍历响应头中与app-alert,app-params相关的信息,调用alertService构造一个成功信息。
值得注意的是:
// tslint:disable-next-line: no-unused-variable
constructor(private injector: Injector) {
super();
setTimeout(() => this.alertService = injector.get(JhiAlertService));
}
为什么需要手工从注入器获取JhiAlertService,而不是直接注入JhiAlertService?
5.http.provider.ts
defaultOptions,
[
new AuthInterceptor(localStorage, sessionStorage),
new AuthExpiredInterceptor(injector),
// Other interceptors can be added here
new ErrorHandlerInterceptor(eventManager),
new NotificationInterceptor(injector)
]
这里定义了Jhipster实现的有拦截器功能的Http客户端,并在app.module.ts中替换掉angular的http。Angular5原生也支持了拦截器,具体实现方式也差不多。
注意这里new 的各个拦截器顺序很重要,JHipster也很贴心提示了,在自己添加拦截器时,修改的位置。
网友评论