搭建一个基于SpringBoot的本地开发环境,可以方便我们开发和调试无服务器云函数和API网关。
设计思路:
- 通过Springboot可以快速启动一个本地的服务。
- 注册一个Component将我们所有的API网关请求的函数注册到服务中。
- 通过添加Filter来拦截所有的请求。
- 在Filter中将Servlet请求封装成API网关的入口参数
Gateway
。 - 调用第2步中的函数进行处理。
注意事项:
一. 跨域访问(CORS)的设置。
由于所有的请求都被拦截,所以在response中要设置能够跨域访问的所有的头信息。
response.setHeader("Access-Control-Allow-Origin", header);
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers",
"X-Api-ID,X-Service-RateLimit,X-UsagePlan-RateLimit,X-UsagePlan-Quota,Cache-Control,Connection,Content-Disposition,Date,Keep-Alive,Pragma,Via,Accept,Accept-Charset,Accept-Encoding,Accept-Language,Authorization,Cookie,Expect,From,Host,If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since,Range,Origin,Referer,User-Agent,X-Forwarded-For,X-Forwarded-Host,X-Forwarded-Proto,Accept-Range,Age,Content-Range,Content-Security-Policy,ETag,Expires,Last-Modified,Location,Server,Set-Cookie,Trailer,Transfer-Encoding,Vary,Allow,Content-Encoding,Content-Language,Content-Length,Content-Location,Content-Type,X-Date,Source,X-Acpt");
response.setHeader("Access-Control-Allow-Credentials", "true");
二. 由于跨域访问一般会进行2次请求,所以一定要先处理预请求信息(OPTIONS)
if (request.getMethod().equals("OPTIONS")) {
response.setStatus(HttpServletResponse.SC_OK);
return;
}
三. 获取Servlet请求的body,一定要在请求最开始的时候获取。(Request被读取一次之后Reader就为空了)
// Get body from very beginning.
if (request instanceof HttpServletRequest) {
if ("POST".equalsIgnoreCase(((HttpServletRequest) request).getMethod())) {
try {
body = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
} catch (IOException e) {
e.printStackTrace();
}
}
}
四. 一定要把Filter的优先级设置为最高
@Order(Ordered.HIGHEST_PRECEDENCE)