feat: complate @ccms/web package
Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
parent
0bc513d580
commit
36c9d4ad99
@ -1,2 +1,16 @@
|
|||||||
export const WebProxyBeanName = 'webServerProxy'
|
export const WebProxyBeanName = 'webServerProxy'
|
||||||
export const FilterProxyBeanName = 'webFilterProxy'
|
export const FilterProxyBeanName = 'webFilterProxy'
|
||||||
|
export const METADATA_KEY = {
|
||||||
|
Controller: Symbol("@ccms/web:Controller"),
|
||||||
|
Action: Symbol("@ccms/web:Action"),
|
||||||
|
Param: Symbol("@ccms/web:Param"),
|
||||||
|
Middleware: Symbol("@ccms/web:Middleware"),
|
||||||
|
}
|
||||||
|
export enum PARAM_TYPE {
|
||||||
|
QUERY = 'QUERY',
|
||||||
|
BODY = 'BODY',
|
||||||
|
HEADER = 'HEADER',
|
||||||
|
COOKIE = 'COOKIE',
|
||||||
|
REQUEST = 'REQUEST',
|
||||||
|
RESPONSE = 'RESPONSE',
|
||||||
|
}
|
||||||
|
@ -1,30 +1,80 @@
|
|||||||
export const Controller = () => {
|
import { decorate, injectable } from "@ccms/container"
|
||||||
return <TFunction extends Function>(target: TFunction): ClassDecorator => {
|
|
||||||
|
import { METADATA_KEY, PARAM_TYPE } from '../constants'
|
||||||
|
import { interfaces } from "../interfaces"
|
||||||
|
import { addControllerMetadata, addControllerAction, addActionParam } from "./utils"
|
||||||
|
|
||||||
|
export const Controller = (metadata?: string | interfaces.ControllerMetadata) => {
|
||||||
|
return (target: any) => {
|
||||||
|
if (!metadata) { metadata = target.name.toLowerCase().replace('controller', '') }
|
||||||
|
if (typeof metadata === "string") { metadata = { path: metadata } }
|
||||||
|
metadata.name = metadata.name || target.name
|
||||||
|
metadata.path = metadata.path ?? `/${metadata}`
|
||||||
|
metadata.path = metadata.path.startsWith('/') ? metadata.path : `/${metadata.path}`
|
||||||
|
decorate(injectable(), target)
|
||||||
|
Reflect.defineMetadata(METADATA_KEY.Controller, metadata, target)
|
||||||
|
addControllerMetadata(metadata)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export const Post = () => {
|
|
||||||
return <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>): MethodDecorator => {
|
function action(method: interfaces.Method) {
|
||||||
|
return (metadata?: string | interfaces.ActionMetadata) => {
|
||||||
|
return (target: any, propertyKey: string) => {
|
||||||
|
if (!metadata) { metadata = propertyKey.toLowerCase() }
|
||||||
|
if (typeof metadata === "string") { metadata = { path: metadata } }
|
||||||
|
metadata.path = metadata.path ?? `/${propertyKey}`
|
||||||
|
metadata.path = metadata.path.startsWith('/') ? metadata.path : `/${metadata.path}`
|
||||||
|
metadata.method = method
|
||||||
|
metadata.executor = propertyKey
|
||||||
|
Reflect.defineMetadata(METADATA_KEY.Action, metadata, target[propertyKey])
|
||||||
|
addControllerAction(target, propertyKey)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export const Get = () => {
|
}
|
||||||
return <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>): MethodDecorator => {
|
export const Action = action('ALL')
|
||||||
|
export const Get = action('GET')
|
||||||
|
export const Post = action('POST')
|
||||||
|
export const Put = action('PUT')
|
||||||
|
export const Patch = action('PATCH')
|
||||||
|
export const Head = action('HEAD')
|
||||||
|
export const Delete = action('DELETE')
|
||||||
|
|
||||||
|
function param(type: PARAM_TYPE) {
|
||||||
|
return (metadata?: string | interfaces.ParamMetadata) => {
|
||||||
|
return (target: any, propertyKey: string, index: number) => {
|
||||||
|
if (!metadata) { metadata = `${propertyKey}-${index}` }
|
||||||
|
if (typeof metadata === "string") { metadata = { name: metadata } }
|
||||||
|
metadata.type = type
|
||||||
|
metadata.index = index
|
||||||
|
metadata.paramtype = Reflect.getMetadata("design:paramtypes", target, propertyKey)[index]
|
||||||
|
addActionParam(target, propertyKey, metadata)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export const Header = () => {
|
}
|
||||||
return <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>): MethodDecorator => {
|
export const Request = param(PARAM_TYPE.REQUEST)
|
||||||
|
export const Response = param(PARAM_TYPE.RESPONSE)
|
||||||
|
export const Header = param(PARAM_TYPE.HEADER)
|
||||||
|
export const Cookie = param(PARAM_TYPE.COOKIE)
|
||||||
|
export const Query = param(PARAM_TYPE.QUERY)
|
||||||
|
export const Param = param(PARAM_TYPE.QUERY)
|
||||||
|
export const Body = param(PARAM_TYPE.BODY)
|
||||||
|
|
||||||
|
function Middleware() {
|
||||||
|
return (metadata?: string | interfaces.ActionMetadata) => {
|
||||||
|
return (target: any, propertyKey: string) => {
|
||||||
|
if (!metadata) { metadata = propertyKey.toLowerCase() }
|
||||||
|
if (typeof metadata === "string") { metadata = { path: metadata } }
|
||||||
|
metadata.path = metadata.path ?? `/${propertyKey}`
|
||||||
|
metadata.path = metadata.path.startsWith('/') ? metadata.path : `/${metadata.path}`
|
||||||
|
metadata.executor = propertyKey
|
||||||
|
Reflect.defineMetadata(METADATA_KEY.Action, metadata, target[propertyKey])
|
||||||
|
addControllerAction(target, propertyKey)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export const Param = () => {
|
|
||||||
return (target: Object, propertyKey: string | symbol, parameterIndex: number): ParameterDecorator => {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export const RequestBody = () => {
|
|
||||||
return (target: Object, propertyKey: string | symbol, parameterIndex: number): ParameterDecorator => {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export * from './utils'
|
||||||
|
27
packages/web/src/decorators/utils.ts
Normal file
27
packages/web/src/decorators/utils.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { interfaces } from '../interfaces'
|
||||||
|
import { METADATA_KEY } from '../constants'
|
||||||
|
|
||||||
|
export function getControllerMetadatas(): interfaces.ControllerMetadata[] {
|
||||||
|
return Reflect.getMetadata(METADATA_KEY.Controller, Reflect) || []
|
||||||
|
}
|
||||||
|
export function addControllerMetadata(metadata: interfaces.ControllerMetadata) {
|
||||||
|
Reflect.defineMetadata(METADATA_KEY.Controller, [metadata, ...getControllerMetadatas()], Reflect)
|
||||||
|
}
|
||||||
|
export function getControllerActions(target: any): string[] {
|
||||||
|
return Reflect.getMetadata(METADATA_KEY.Action, target.constructor) || []
|
||||||
|
}
|
||||||
|
export function addControllerAction(target: any, propertyKey: string) {
|
||||||
|
Reflect.defineMetadata(METADATA_KEY.Action, [propertyKey, ...getControllerActions(target)], target.constructor)
|
||||||
|
}
|
||||||
|
export function getControllerMetadata(target: any): interfaces.ControllerMetadata {
|
||||||
|
return Reflect.getMetadata(METADATA_KEY.Controller, target)
|
||||||
|
}
|
||||||
|
export function getActionMetadata(target: any, propertyKey: string): interfaces.ActionMetadata {
|
||||||
|
return Reflect.getMetadata(METADATA_KEY.Action, target[propertyKey])
|
||||||
|
}
|
||||||
|
export function getActionParams(target: any, propertyKey: string): interfaces.ParamMetadata[] {
|
||||||
|
return Reflect.getMetadata(METADATA_KEY.Param, target[propertyKey]) || []
|
||||||
|
}
|
||||||
|
export function addActionParam(target: any, propertyKey: string, metadata: interfaces.ParamMetadata) {
|
||||||
|
Reflect.defineMetadata(METADATA_KEY.Param, [metadata, ...getActionParams(target, propertyKey)], target[propertyKey])
|
||||||
|
}
|
@ -6,5 +6,6 @@
|
|||||||
/// <reference types="@javatypes/spring-beans" />
|
/// <reference types="@javatypes/spring-beans" />
|
||||||
|
|
||||||
export * from './server'
|
export * from './server'
|
||||||
|
export * from './constants'
|
||||||
export * from './decorators'
|
export * from './decorators'
|
||||||
export * from './interfaces'
|
export * from './interfaces'
|
||||||
|
@ -5,14 +5,20 @@ export interface InterceptorAdapter {
|
|||||||
postHandle?(ctx: Context): void
|
postHandle?(ctx: Context): void
|
||||||
}
|
}
|
||||||
|
|
||||||
export type RequestHeader = { [key: string]: string | string[] }
|
type StringKeyAndStringValue = { [key: string]: string }
|
||||||
export type RequestParams = { [key: string]: string | string[] }
|
type StringKeyAndStringOrArrayValue = { [key: string]: string | string[] }
|
||||||
|
|
||||||
|
export type RequestHeaders = StringKeyAndStringOrArrayValue
|
||||||
|
export type RequestParams = StringKeyAndStringOrArrayValue
|
||||||
|
export type RequestCookies = StringKeyAndStringValue
|
||||||
|
|
||||||
export interface Context {
|
export interface Context {
|
||||||
request?: javax.servlet.http.HttpServletRequest
|
request?: javax.servlet.http.HttpServletRequest
|
||||||
response?: javax.servlet.http.HttpServletResponse
|
response?: javax.servlet.http.HttpServletResponse
|
||||||
header?: RequestHeader
|
handler?: RequestHandler
|
||||||
url?: string
|
url?: string
|
||||||
|
headers?: RequestHeaders
|
||||||
|
cookies?: RequestCookies
|
||||||
params?: RequestParams
|
params?: RequestParams
|
||||||
body?: any
|
body?: any
|
||||||
result?: any
|
result?: any
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
import { PARAM_TYPE } from "../constants"
|
||||||
|
|
||||||
|
export namespace interfaces {
|
||||||
export interface BaseMetadata {
|
export interface BaseMetadata {
|
||||||
/**
|
/**
|
||||||
* 名称 为空则为对象名称
|
* 名称 为空则为对象名称
|
||||||
@ -8,7 +11,67 @@ export interface BaseMetadata {
|
|||||||
*/
|
*/
|
||||||
servers?: string[]
|
servers?: string[]
|
||||||
}
|
}
|
||||||
|
export interface WebMetadata extends BaseMetadata {
|
||||||
export interface ControllerMetadata extends BaseMetadata {
|
/**
|
||||||
|
* 路径
|
||||||
|
*/
|
||||||
|
path: string
|
||||||
|
/**
|
||||||
|
* 对象
|
||||||
|
*/
|
||||||
|
target?: string
|
||||||
|
}
|
||||||
|
export interface ControllerMetadata extends WebMetadata {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
interface Newable<T> {
|
||||||
|
new(...args: any[]): T
|
||||||
|
}
|
||||||
|
interface Abstract<T> {
|
||||||
|
prototype: T
|
||||||
|
}
|
||||||
|
export type ServiceIdentifier<T> = (string | symbol | Newable<T> | Abstract<T>)
|
||||||
|
export interface MiddlewareMetadata extends BaseMetadata {
|
||||||
|
/**
|
||||||
|
* 中间件名称列表
|
||||||
|
*/
|
||||||
|
names: Array<ServiceIdentifier<any>>
|
||||||
|
}
|
||||||
|
export type Method = 'ALL' | 'GET' | 'HEAD' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS' | 'TRACE'
|
||||||
|
export interface ActionMetadata extends WebMetadata {
|
||||||
|
/**
|
||||||
|
* 请求方法
|
||||||
|
*/
|
||||||
|
method?: Method
|
||||||
|
/**
|
||||||
|
* 执行器
|
||||||
|
*/
|
||||||
|
executor?: string
|
||||||
|
}
|
||||||
|
export interface ParamMetadata extends BaseMetadata {
|
||||||
|
/**
|
||||||
|
* 参数类型
|
||||||
|
*/
|
||||||
|
type?: PARAM_TYPE
|
||||||
|
/**
|
||||||
|
* 默认值
|
||||||
|
*/
|
||||||
|
default?: any
|
||||||
|
/**
|
||||||
|
* 参数位置
|
||||||
|
*/
|
||||||
|
index?: number
|
||||||
|
/**
|
||||||
|
* 参数对象类型
|
||||||
|
*/
|
||||||
|
paramtype?: NewableFunction
|
||||||
|
/**
|
||||||
|
* 是否必传
|
||||||
|
*/
|
||||||
|
require?: boolean
|
||||||
|
/**
|
||||||
|
* 异常消息
|
||||||
|
*/
|
||||||
|
message?: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,10 +1,16 @@
|
|||||||
import * as querystring from 'querystring'
|
import * as querystring from 'querystring'
|
||||||
|
|
||||||
import { web } from '@ccms/api'
|
import { web } from '@ccms/api'
|
||||||
import { provideSingleton, JSClass, postConstruct } from '@ccms/container'
|
import { provideSingleton, JSClass, postConstruct, Container, ContainerInstance, inject } from '@ccms/container'
|
||||||
|
|
||||||
import { WebProxyBeanName, FilterProxyBeanName } from './constants'
|
import { WebProxyBeanName, FilterProxyBeanName, METADATA_KEY, PARAM_TYPE } from './constants'
|
||||||
import { Context, InterceptorAdapter, RequestHandler } from './interfaces'
|
import { Context, InterceptorAdapter, RequestHandler, interfaces } from './interfaces'
|
||||||
|
import { getControllerActions, getActionMetadata, getControllerMetadata, getActionParams } from './decorators'
|
||||||
|
|
||||||
|
const HttpServletRequestWrapper = Java.type('javax.servlet.http.HttpServletRequestWrapper')
|
||||||
|
const HttpServletResponseWrapper = Java.type('javax.servlet.http.HttpServletResponseWrapper')
|
||||||
|
const ServletInputStream = Java.type('javax.servlet.ServletInputStream')
|
||||||
|
const ServletOutputStream = Java.type('javax.servlet.ServletOutputStream')
|
||||||
|
|
||||||
@provideSingleton(web.Server)
|
@provideSingleton(web.Server)
|
||||||
export class Server {
|
export class Server {
|
||||||
@ -13,11 +19,14 @@ export class Server {
|
|||||||
@JSClass('pw.yumc.MiaoScript.web.WebFilterProxy')
|
@JSClass('pw.yumc.MiaoScript.web.WebFilterProxy')
|
||||||
private WebFilterProxy: any
|
private WebFilterProxy: any
|
||||||
|
|
||||||
|
@inject(ContainerInstance)
|
||||||
|
private container: Container
|
||||||
|
|
||||||
private StreamUtils = org.springframework.util.StreamUtils
|
private StreamUtils = org.springframework.util.StreamUtils
|
||||||
private ResponseEntity = org.springframework.http.ResponseEntity
|
private ResponseEntity = org.springframework.http.ResponseEntity
|
||||||
|
|
||||||
private interceptors: Map<string, InterceptorAdapter>
|
private interceptors: Map<string, InterceptorAdapter>
|
||||||
private handlerMapping: Map<string, RequestHandler>
|
private methodMappings: Map<string, Map<string, RequestHandler>>
|
||||||
|
|
||||||
private beanFactory: org.springframework.beans.factory.support.DefaultListableBeanFactory
|
private beanFactory: org.springframework.beans.factory.support.DefaultListableBeanFactory
|
||||||
|
|
||||||
@ -25,7 +34,7 @@ export class Server {
|
|||||||
initialization() {
|
initialization() {
|
||||||
this.beanFactory = base.getInstance().getAutowireCapableBeanFactory()
|
this.beanFactory = base.getInstance().getAutowireCapableBeanFactory()
|
||||||
this.interceptors = new Map()
|
this.interceptors = new Map()
|
||||||
this.handlerMapping = new Map()
|
this.methodMappings = new Map()
|
||||||
this.start()
|
this.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,13 +52,77 @@ export class Server {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registryController(target: any) {
|
||||||
|
if (!target) { throw new Error('Controller can\'t be undefiend!') }
|
||||||
|
let controllerMetadata = getControllerMetadata(target)
|
||||||
|
if (!controllerMetadata) { throw new Error(`Controller ${target.name} must have @Controller decorator!`) }
|
||||||
|
try {
|
||||||
|
this.container.rebind(METADATA_KEY.Controller).to(target).inSingletonScope().whenTargetNamed(target.name)
|
||||||
|
} catch{
|
||||||
|
this.container.bind(METADATA_KEY.Controller).to(target).inSingletonScope().whenTargetNamed(target.name)
|
||||||
|
}
|
||||||
|
target = this.container.getNamed(METADATA_KEY.Controller, target.name)
|
||||||
|
let actions = getControllerActions(target)
|
||||||
|
for (const action of actions) {
|
||||||
|
let actionMetadata = getActionMetadata(target, action)
|
||||||
|
let path = `${controllerMetadata.path || ''}${actionMetadata.path || ''}`
|
||||||
|
if (!path) throw new Error(`Controller ${controllerMetadata.name} Action ${actionMetadata.name} path is empty!`)
|
||||||
|
if (!this.methodMappings.has(path)) { this.methodMappings.set(path, new Map()) }
|
||||||
|
console.debug(`Controller ${controllerMetadata.name} Registry ${path} to ${actionMetadata.executor || '<anonymous>'} Action function.`)
|
||||||
|
this.methodMappings.get(path).set(actionMetadata.method || 'ALL', (ctx: Context) => {
|
||||||
|
let args = []
|
||||||
|
let params = getActionParams(target, action)
|
||||||
|
for (const index in params) {
|
||||||
|
let param = params[index]
|
||||||
|
let paramValue = undefined
|
||||||
|
switch (param.type) {
|
||||||
|
case PARAM_TYPE.REQUEST: paramValue = ctx.request; break
|
||||||
|
case PARAM_TYPE.RESPONSE: paramValue = ctx.response; break
|
||||||
|
case PARAM_TYPE.QUERY: paramValue = ctx.params[param.name]; break
|
||||||
|
case PARAM_TYPE.HEADER: paramValue = ctx.headers[param.name]; break
|
||||||
|
case PARAM_TYPE.BODY: paramValue = ctx.body; break
|
||||||
|
case PARAM_TYPE.COOKIE: paramValue = ctx.cookies[param.name]; break
|
||||||
|
}
|
||||||
|
if (param.require && !paramValue) {
|
||||||
|
return {
|
||||||
|
status: 400,
|
||||||
|
msg: param.message ?? `Param Type ${param.type} require not empty!`,
|
||||||
|
data: param
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args[param.index] = paramValue ?? param.default
|
||||||
|
}
|
||||||
|
return target[actionMetadata.executor].apply(target, args)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unregistryController(target: any) {
|
||||||
|
if (!target) { throw new Error('Controller can\'t be undefiend!') }
|
||||||
|
let controllerMetadata = getControllerMetadata(target)
|
||||||
|
if (!controllerMetadata) { throw new Error(`Controller ${target.name} must have @Controller decorator!`) }
|
||||||
|
try {
|
||||||
|
target = this.container.getNamed(METADATA_KEY.Controller, target.name)
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(`Controller ${target.name} not registry! err: ${error}`)
|
||||||
|
}
|
||||||
|
let actions = getControllerActions(target)
|
||||||
|
for (const action of actions) {
|
||||||
|
let actionMetadata = getActionMetadata(target, action)
|
||||||
|
let path = `${controllerMetadata.path || ''}${actionMetadata.path || ''}`
|
||||||
|
if (!this.methodMappings.has(path)) { continue }
|
||||||
|
this.methodMappings.get(path).delete(actionMetadata.method)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
registryMapping(path: string, handler: RequestHandler) {
|
registryMapping(path: string, handler: RequestHandler) {
|
||||||
console.debug(`Registry Mapping ${path} to handle ${handler.name || '<anonymous>'} function.`)
|
console.debug(`Registry Mapping ${path} to handle ${handler.name || '<anonymous>'} function.`)
|
||||||
this.handlerMapping.set(path, handler)
|
if (!this.methodMappings.has(path)) { this.methodMappings.set(path, new Map()) }
|
||||||
|
this.methodMappings.get(path).set("ALL", handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
unregistryMapping(path: string) {
|
unregistryMapping(path: string) {
|
||||||
this.handlerMapping.delete(path)
|
if (this.methodMappings.has(path)) { this.methodMappings.get(path).delete("ALL") }
|
||||||
}
|
}
|
||||||
|
|
||||||
registryInterceptor(interceptor: InterceptorAdapter) {
|
registryInterceptor(interceptor: InterceptorAdapter) {
|
||||||
@ -65,28 +138,72 @@ export class Server {
|
|||||||
try { this.beanFactory.destroySingleton(FilterProxyBeanName) } catch (ex) { }
|
try { this.beanFactory.destroySingleton(FilterProxyBeanName) } catch (ex) { }
|
||||||
var WebFilterProxyNashorn = Java.extend(this.WebFilterProxy, {
|
var WebFilterProxyNashorn = Java.extend(this.WebFilterProxy, {
|
||||||
doFilter: (servletRequest: javax.servlet.http.HttpServletRequest, servletResponse: javax.servlet.http.HttpServletResponse, filterChain: javax.servlet.FilterChain) => {
|
doFilter: (servletRequest: javax.servlet.http.HttpServletRequest, servletResponse: javax.servlet.http.HttpServletResponse, filterChain: javax.servlet.FilterChain) => {
|
||||||
console.log('WebFilterProxyNashorn', 'doFilter', servletRequest, servletResponse)
|
|
||||||
filterChain.doFilter(servletRequest, servletResponse)
|
filterChain.doFilter(servletRequest, servletResponse)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.beanFactory.registerSingleton(FilterProxyBeanName, new WebFilterProxyNashorn())
|
this.beanFactory.registerSingleton(FilterProxyBeanName, new WebFilterProxyNashorn())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// private getRequestWrapper(servletRequest: javax.servlet.http.HttpServletRequest) {
|
||||||
|
// var body = org.springframework.util.StreamUtils.copyToByteArray(servletRequest.getInputStream())
|
||||||
|
// var HttpServletRequestWrapperAdapter = Java.extend(HttpServletRequestWrapper, {
|
||||||
|
// getInputStream: () => {
|
||||||
|
// var bais = new java.io.ByteArrayInputStream(body)
|
||||||
|
// return new ServletInputStream({
|
||||||
|
// read: () => bais.read(),
|
||||||
|
// isFinished: () => bais.available() == 0
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// var wrapper = new HttpServletRequestWrapperAdapter(servletRequest)
|
||||||
|
// return wrapper
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private getResponseWrapper(servletResponse: javax.servlet.http.HttpServletResponse) {
|
||||||
|
// var HttpServletRequestWrapperAdapter = Java.extend(HttpServletRequestWrapper, {
|
||||||
|
// getOutputStream: () => {
|
||||||
|
// return new ServletOutputStream({
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// var wrapper = new HttpServletRequestWrapperAdapter(servletResponse)
|
||||||
|
// return wrapper
|
||||||
|
// }
|
||||||
|
|
||||||
|
private notFound(method: string, path: string) {
|
||||||
|
return {
|
||||||
|
status: 404,
|
||||||
|
msg: "handlerMapping Not Found!",
|
||||||
|
method,
|
||||||
|
path,
|
||||||
|
timestamp: Date.now()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private registryWebProxy() {
|
private registryWebProxy() {
|
||||||
try { this.beanFactory.destroySingleton(WebProxyBeanName) } catch (ex) { }
|
try { this.beanFactory.destroySingleton(WebProxyBeanName) } catch (ex) { }
|
||||||
var WebServerProxyNashorn = Java.extend(this.WebServerProxy, {
|
var WebServerProxyNashorn = Java.extend(this.WebServerProxy, {
|
||||||
process: (req: javax.servlet.http.HttpServletRequest, resp: javax.servlet.http.HttpServletResponse) => {
|
process: (req: javax.servlet.http.HttpServletRequest, resp: javax.servlet.http.HttpServletResponse) => {
|
||||||
let ctx: Context = { request: req, response: resp }
|
let path = req.getRequestURI()
|
||||||
|
if (!this.methodMappings.has(path)) return this.notFound(req.getMethod(), path)
|
||||||
|
let mappings = this.methodMappings.get(req.getRequestURI())
|
||||||
|
let handler = mappings.get(req.getMethod()) || mappings.get("ALL")
|
||||||
|
if (!handler) return this.notFound(req.getMethod(), path)
|
||||||
|
let ctx: Context = { request: req, response: resp, params: {}, body: {}, handler }
|
||||||
ctx.url = req.getRequestURI()
|
ctx.url = req.getRequestURI()
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
ctx.header = { __noSuchProperty__: (name: string) => req.getHeader(name) + '' }
|
ctx.headers = { __noSuchProperty__: (name: string) => req.getHeader(name) }
|
||||||
|
ctx.cookies = {}
|
||||||
|
for (const cookie of (req.getCookies() || [])) {
|
||||||
|
ctx.cookies[cookie.getName()] = cookie.getValue()
|
||||||
|
}
|
||||||
if (req.getQueryString()) {
|
if (req.getQueryString()) {
|
||||||
ctx.url += `?${req.getQueryString()}`
|
ctx.url += `?${req.getQueryString()}`
|
||||||
ctx.params = querystring.parse(req.getQueryString())
|
ctx.params = querystring.parse(req.getQueryString())
|
||||||
}
|
}
|
||||||
if (req.getMethod() == "POST") {
|
if (req.getMethod() == "POST") {
|
||||||
ctx.body = this.StreamUtils.copyToString(req.getInputStream(), java.nio.charset.StandardCharsets.UTF_8)
|
ctx.body = this.StreamUtils.copyToString(req.getInputStream(), java.nio.charset.StandardCharsets.UTF_8)
|
||||||
if ((ctx.header['Content-Type'] || '').includes('application/json')) {
|
if ((ctx.headers['Content-Type'] || '').includes('application/json')) {
|
||||||
try {
|
try {
|
||||||
ctx.body = JSON.parse(ctx.body)
|
ctx.body = JSON.parse(ctx.body)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -158,6 +275,7 @@ export class Server {
|
|||||||
===================== MiaoSpring =====================
|
===================== MiaoSpring =====================
|
||||||
Request Method : ${ctx.request.getMethod()}
|
Request Method : ${ctx.request.getMethod()}
|
||||||
Request URL : ${ctx.url}
|
Request URL : ${ctx.url}
|
||||||
|
Request Body : ${JSON.stringify(ctx.body)}
|
||||||
Response Body : ${JSON.stringify(Java.asJSONCompatible(ctx.result))}
|
Response Body : ${JSON.stringify(Java.asJSONCompatible(ctx.result))}
|
||||||
Handle Time : ${Date.now() - startTime}ms
|
Handle Time : ${Date.now() - startTime}ms
|
||||||
======================================================`)
|
======================================================`)
|
||||||
@ -165,16 +283,8 @@ Handle Time : ${Date.now() - startTime}ms
|
|||||||
}
|
}
|
||||||
|
|
||||||
private execRequestHandle(ctx: Context) {
|
private execRequestHandle(ctx: Context) {
|
||||||
if (!this.handlerMapping.has(ctx.request.getRequestURI())) {
|
|
||||||
return {
|
|
||||||
status: 404,
|
|
||||||
msg: "handlerMapping Not Found!",
|
|
||||||
path: ctx.url,
|
|
||||||
timestamp: Date.now()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
return this.handlerMapping.get(ctx.request.getRequestURI())(ctx)
|
return ctx.handler(ctx)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
status: 500,
|
status: 500,
|
||||||
|
Loading…
Reference in New Issue
Block a user