源码: j-spring-eco ts版本的Spring全家桶
前言
熟悉springWeb的都知道,参数反射。
@Get()
@ApiRemark('测试反射')
async testQuery3(
@RequestParam('a') a: number,
@RequestParam('ids') ids: ArrayNumber,
@Param() req: Request,
@Param() res: Response,
@Param() session: Session
) {
return {};
}
语言层面,相比较java版本的,ts确实要稍微麻烦了一点。例如@RequestParam 需要手动输入参数名,req: Request需要添加注解。且Request必须是一个类(函数)。
整体还能接受,不算特别麻烦。带来的便利性也是不言而喻的。相比express的router明显更加直观和便捷,顺便还做了一次参数检查。
麻烦点
express 4.x是js编写的,随之tds文件肯定是手动编写的了。描述文件里面的Request和Response是一个接口,这是无法用于加在参数后面作为反射类型的,因为接口在编译的时候就清除了。
如果在项目里面实现Request和Response接口,即使有自动生成接口的模板代码,但是依旧非常的麻烦。将近一千行,还得一行行改,还有包的依赖问题,瞬间没有心情了。
解决办法
1、创建一个包
创建一个j-spring-type-wrap项目,就是用j-spring-cli创建一个模板项目
2、创建一些简单的实现类 index.ts
```js
//这些类本身没有意义,只是为了参数反射使用。只需要类名就行了
//添加Abs后缀是放置和自动生成的tds代码起冲突
export class RequestAbs {}
export class ResponseAbs {}
export class ExpressServerAbs {}
export class ExpressAppAbs {}
```
3、手动实现 index.tds
import {
Request,
MediaType,
ParamsDictionary,
Response,
NextFunction,
CookieOptions,
Errback,
Application,
RequestParamHandler,
Send,
} from 'express-serve-static-core';
export class RequestAbs implements Request {
// vs-code会自动把Request的接口实现。不需要额外编辑。
}
- 代码太长了接近上千行,好在都是自动生成的。
- 这个包就完成了,发布就完事了。
项目里面使用
- 导出类
import {
RequestAbs as Request,
ResponseAbs as Response,
ExpressAppAbs as ExpressApp,
ExpressServerAbs as ExpressServer,
} from 'j-spring-type-wrap';
export { Request, Response, ExpressApp, ExpressServer };
- 添加参数拦截器
class ParamInteceptor implements SpringWebParamInteceptor<any> {
error(_bean: any): void {}
success(_bean: any): void {}
isSpringWebParamInteceptor(): boolean {
return true;
}
getAnnotation(): Function {
return Param;
}
getBean(req: Request, res: Response, pa: Anntation) {
const { reflectType } = pa.params as ReflectParam;
if (reflectType === Request) return req;
if (reflectType === Response) return res;
if (reflectType === Session) {
if (req.session === void 0) {
throw '没有安装session插件';
}
return new Session(req.session);
}
throw `不支持参数反射类型: [${reflectType}]`;
}
}