From ed3aa1ef4bd2dc698f3918757964f3723f03768a Mon Sep 17 00:00:00 2001 From: jmxd <838425805@qq.com> Date: Wed, 15 Mar 2023 11:01:05 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=82=E9=85=8DSpring=20Boot=203.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +- ...ot.autoconfigure.AutoConfiguration.imports | 1 + ...ot.autoconfigure.AutoConfiguration.imports | 1 + ...ot.autoconfigure.AutoConfiguration.imports | 1 + .../main/resources/META-INF/spring.factories | 3 +- ...ot.autoconfigure.AutoConfiguration.imports | 1 + ...ot.autoconfigure.AutoConfiguration.imports | 1 + .../magic-api-plugin-redis/pom.xml | 5 + ...ot.autoconfigure.AutoConfiguration.imports | 1 + .../swagger/entity/SwaggerProvider.java | 8 +- ...ot.autoconfigure.AutoConfiguration.imports | 1 + .../task/web/MagicTaskController.java | 4 +- ...ot.autoconfigure.AutoConfiguration.imports | 1 + .../magic-api-servlet-jakarta/pom.xml | 40 ++++++ .../servlet/jakarta/MagicJakartaCookie.java | 27 ++++ .../jakarta/MagicJakartaCorsFilter.java | 17 +++ .../MagicJakartaHttpServletRequest.java | 127 ++++++++++++++++++ .../MagicJakartaHttpServletResponse.java | 68 ++++++++++ .../jakarta/MagicJakartaHttpSession.java | 24 ++++ .../MagicJakartaRequestContextHolder.java | 25 ++++ .../MagicJakartaResponseExtension.java | 104 ++++++++++++++ .../MagicJakartaServletConfiguration.java | 69 ++++++++++ .../MagicJakartaWebRequestInterceptor.java | 23 ++++ .../magic-api-servlet-javaee/pom.xml | 18 +++ .../servlet/javaee/MagicJavaEECookie.java | 28 ++++ .../servlet/javaee/MagicJavaEECorsFilter.java | 17 +++ .../javaee/MagicJavaEEHttpServletRequest.java | 126 +++++++++++++++++ .../MagicJavaEEHttpServletResponse.java | 69 ++++++++++ .../javaee/MagicJavaEEHttpSession.java | 24 ++++ .../MagicJavaEERequestContextHolder.java | 25 ++++ .../javaee/MagicJavaEEResponseExtension.java | 104 ++++++++++++++ .../MagicJavaEEServletConfiguration.java | 69 ++++++++++ .../MagicJavaEEWebRequestInterceptor.java | 23 ++++ magic-api-servlet/pom.xml | 25 ++++ magic-api-spring-boot-starter/pom.xml | 8 ++ .../starter/MagicAPIAutoConfiguration.java | 56 +++----- .../starter/MagicModuleConfiguration.java | 5 +- .../starter/MagicServletConfiguration.java | 40 ++++++ ...ot.autoconfigure.AutoConfiguration.imports | 1 + .../magicapi/core/config/MagicCorsFilter.java | 46 ++----- .../magicapi/core/context/CookieContext.java | 13 +- .../magicapi/core/context/RequestContext.java | 9 +- .../magicapi/core/context/RequestEntity.java | 16 +-- .../magicapi/core/context/SessionContext.java | 7 +- .../interceptor/AuthorizationInterceptor.java | 9 +- .../MagicWebRequestInterceptor.java | 20 +-- .../core/interceptor/RequestInterceptor.java | 12 +- .../magicapi/core/model/DebugRequest.java | 10 +- .../service/impl/DefaultMagicAPIService.java | 25 ++-- .../impl/RequestMagicDynamicRegistry.java | 10 +- .../magicapi/core/servlet/MagicCookie.java | 8 ++ .../core/servlet/MagicHttpServletRequest.java | 46 +++++++ .../servlet/MagicHttpServletResponse.java | 20 +++ .../core/servlet/MagicHttpSession.java | 8 ++ .../servlet/MagicRequestContextHolder.java | 23 ++++ .../magicapi/core/web/MagicController.java | 22 +-- .../core/web/MagicResourceController.java | 22 +-- .../core/web/MagicWorkbenchController.java | 34 ++--- .../magicapi/core/web/RequestHandler.java | 25 ++-- .../modules/servlet/RequestModule.java | 33 ++--- .../modules/servlet/ResponseModule.java | 100 +------------- .../org/ssssssss/magicapi/utils/WebUtils.java | 19 +-- pom.xml | 20 ++- 63 files changed, 1418 insertions(+), 333 deletions(-) create mode 100644 magic-api-plugins/magic-api-plugin-cluster/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 magic-api-plugins/magic-api-plugin-component/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 magic-api-plugins/magic-api-plugin-elasticsearch/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 magic-api-plugins/magic-api-plugin-git/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 magic-api-plugins/magic-api-plugin-mongo/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 magic-api-plugins/magic-api-plugin-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 magic-api-plugins/magic-api-plugin-swagger/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 magic-api-plugins/magic-api-plugin-task/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 magic-api-servlet/magic-api-servlet-jakarta/pom.xml create mode 100644 magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaCookie.java create mode 100644 magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaCorsFilter.java create mode 100644 magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaHttpServletRequest.java create mode 100644 magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaHttpServletResponse.java create mode 100644 magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaHttpSession.java create mode 100644 magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaRequestContextHolder.java create mode 100644 magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaResponseExtension.java create mode 100644 magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaServletConfiguration.java create mode 100644 magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaWebRequestInterceptor.java create mode 100644 magic-api-servlet/magic-api-servlet-javaee/pom.xml create mode 100644 magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEECookie.java create mode 100644 magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEECorsFilter.java create mode 100644 magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEEHttpServletRequest.java create mode 100644 magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEEHttpServletResponse.java create mode 100644 magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEEHttpSession.java create mode 100644 magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEERequestContextHolder.java create mode 100644 magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEEResponseExtension.java create mode 100644 magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEEServletConfiguration.java create mode 100644 magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEEWebRequestInterceptor.java create mode 100644 magic-api-servlet/pom.xml create mode 100644 magic-api-spring-boot-starter/src/main/java/org/ssssssss/magicapi/spring/boot/starter/MagicServletConfiguration.java create mode 100644 magic-api-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 magic-api/src/main/java/org/ssssssss/magicapi/core/servlet/MagicCookie.java create mode 100644 magic-api/src/main/java/org/ssssssss/magicapi/core/servlet/MagicHttpServletRequest.java create mode 100644 magic-api/src/main/java/org/ssssssss/magicapi/core/servlet/MagicHttpServletResponse.java create mode 100644 magic-api/src/main/java/org/ssssssss/magicapi/core/servlet/MagicHttpSession.java create mode 100644 magic-api/src/main/java/org/ssssssss/magicapi/core/servlet/MagicRequestContextHolder.java diff --git a/README.md b/README.md index 6ba1d8e6..7cc28a0a 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ - +

[特性](#特性) | [快速开始](#快速开始) | [文档/演示](#文档演示) | [示例项目](#示例项目) | 更新日志 | [项目截图](#项目截图) @@ -21,7 +21,7 @@ magic-api 是一个基于Java的接口快速开发框架,编写接口将通过magic-api提供的UI界面完成,自动映射为HTTP接口,无需定义Controller、Service、Dao、Mapper、XML、VO等Java对象即可完成常见的HTTP API接口开发 -【已有上千家中小型公司使用,上万名开发者用于接口配置开发。上百名开发者参与提交了功能建议,接近20多名贡献者参与。已被gitee长期推荐。从首个版本开始不断优化升级,目前版本稳定,开发者交流群活跃。参与交流QQ群③739235910】 +【已有上千家中小型公司使用,上万名开发者用于接口配置开发。上百名开发者参与提交了功能建议,接近20多名贡献者参与。已被gitee长期推荐。从首个版本开始不断优化升级,目前版本稳定,开发者交流群活跃。参与交流QQ群④700818216】 # 特性 - 支持MySQL、MariaDB、Oracle、DB2、PostgreSQL、SQLServer 等支持jdbc规范的数据库 diff --git a/magic-api-plugins/magic-api-plugin-cluster/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/magic-api-plugins/magic-api-plugin-cluster/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..bbfa37d6 --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-cluster/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.ssssssss.magicapi.cluster.MagicClusterConfiguration \ No newline at end of file diff --git a/magic-api-plugins/magic-api-plugin-component/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/magic-api-plugins/magic-api-plugin-component/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..ab6d64a1 --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-component/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.ssssssss.magicapi.component.starter.MagicAPIComponentConfiguration \ No newline at end of file diff --git a/magic-api-plugins/magic-api-plugin-elasticsearch/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/magic-api-plugins/magic-api-plugin-elasticsearch/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..81996353 --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-elasticsearch/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.ssssssss.magicapi.elasticsearch.MagicElasticSearchConfiguration \ No newline at end of file diff --git a/magic-api-plugins/magic-api-plugin-git/src/main/resources/META-INF/spring.factories b/magic-api-plugins/magic-api-plugin-git/src/main/resources/META-INF/spring.factories index faf9674c..2c90cacd 100644 --- a/magic-api-plugins/magic-api-plugin-git/src/main/resources/META-INF/spring.factories +++ b/magic-api-plugins/magic-api-plugin-git/src/main/resources/META-INF/spring.factories @@ -1,2 +1 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ - org.ssssssss.magicapi.git.MagicGitConfiguration +org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.ssssssss.magicapi.git.MagicGitConfiguration diff --git a/magic-api-plugins/magic-api-plugin-git/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/magic-api-plugins/magic-api-plugin-git/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..43a85e4f --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-git/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.ssssssss.magicapi.git.MagicGitConfiguration \ No newline at end of file diff --git a/magic-api-plugins/magic-api-plugin-mongo/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/magic-api-plugins/magic-api-plugin-mongo/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..5c94242a --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-mongo/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.ssssssss.magicapi.mongo.MagicMongoConfiguration \ No newline at end of file diff --git a/magic-api-plugins/magic-api-plugin-redis/pom.xml b/magic-api-plugins/magic-api-plugin-redis/pom.xml index 26dff9b5..d5dca673 100644 --- a/magic-api-plugins/magic-api-plugin-redis/pom.xml +++ b/magic-api-plugins/magic-api-plugin-redis/pom.xml @@ -17,5 +17,10 @@ org.springframework.boot spring-boot-starter-data-redis + + org.redisson + redisson-spring-data-23 + 3.15.6 + diff --git a/magic-api-plugins/magic-api-plugin-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/magic-api-plugins/magic-api-plugin-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..42df19d1 --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.ssssssss.magicapi.redis.MagicRedisConfiguration \ No newline at end of file diff --git a/magic-api-plugins/magic-api-plugin-swagger/src/main/java/org/ssssssss/magicapi/swagger/entity/SwaggerProvider.java b/magic-api-plugins/magic-api-plugin-swagger/src/main/java/org/ssssssss/magicapi/swagger/entity/SwaggerProvider.java index b119cbdd..20c47f91 100644 --- a/magic-api-plugins/magic-api-plugin-swagger/src/main/java/org/ssssssss/magicapi/swagger/entity/SwaggerProvider.java +++ b/magic-api-plugins/magic-api-plugin-swagger/src/main/java/org/ssssssss/magicapi/swagger/entity/SwaggerProvider.java @@ -89,7 +89,7 @@ public class SwaggerProvider { if (this.persistenceResponseBody) { baseDefinition = info.getResponseBodyDefinition(); if (baseDefinition != null) { - Map responseMap = parseResponse(info); + Map responseMap = parseResponse(info); if (!responseMap.isEmpty()) { path.setResponses(responseMap); doProcessDefinition(baseDefinition, info, groupName, "root_" + baseDefinition.getName(), "response", 0); @@ -114,9 +114,9 @@ public class SwaggerProvider { } if (this.DEFINITION_MAP.size() > 0) { - Set entries = ((Map) this.DEFINITION_MAP).entrySet(); - for (Map.Entry entry : entries) { - swaggerEntity.addDefinitions(Objects.toString(entry.getKey()), entry.getValue()); + Set> entries =this.DEFINITION_MAP.entrySet(); + for (Map.Entry entry : entries) { + swaggerEntity.addDefinitions(entry.getKey(), entry.getValue()); } } diff --git a/magic-api-plugins/magic-api-plugin-swagger/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/magic-api-plugins/magic-api-plugin-swagger/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..f83baa4d --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-swagger/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.ssssssss.magicapi.swagger.MagicSwaggerConfiguration \ No newline at end of file diff --git a/magic-api-plugins/magic-api-plugin-task/src/main/java/org/ssssssss/magicapi/task/web/MagicTaskController.java b/magic-api-plugins/magic-api-plugin-task/src/main/java/org/ssssssss/magicapi/task/web/MagicTaskController.java index 02823238..e2348725 100644 --- a/magic-api-plugins/magic-api-plugin-task/src/main/java/org/ssssssss/magicapi/task/web/MagicTaskController.java +++ b/magic-api-plugins/magic-api-plugin-task/src/main/java/org/ssssssss/magicapi/task/web/MagicTaskController.java @@ -8,12 +8,12 @@ import org.ssssssss.magicapi.core.logging.MagicLoggerContext; import org.ssssssss.magicapi.core.model.DebugRequest; import org.ssssssss.magicapi.core.model.JsonBean; import org.ssssssss.magicapi.core.model.MagicEntity; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest; import org.ssssssss.magicapi.core.web.MagicController; import org.ssssssss.magicapi.core.web.MagicExceptionHandler; import org.ssssssss.magicapi.utils.ScriptManager; import org.ssssssss.script.MagicScriptDebugContext; -import javax.servlet.http.HttpServletRequest; public class MagicTaskController extends MagicController implements MagicExceptionHandler { @@ -23,7 +23,7 @@ public class MagicTaskController extends MagicController implements MagicExcepti @PostMapping("/task/execute") @ResponseBody - public JsonBean execute(String id, HttpServletRequest request){ + public JsonBean execute(String id, MagicHttpServletRequest request){ MagicEntity entity = MagicConfiguration.getMagicResourceService().file(id); notNull(entity, FILE_NOT_FOUND); String script = entity.getScript(); diff --git a/magic-api-plugins/magic-api-plugin-task/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/magic-api-plugins/magic-api-plugin-task/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..797fcc9c --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-task/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.ssssssss.magicapi.task.starter.MagicAPITaskConfiguration \ No newline at end of file diff --git a/magic-api-servlet/magic-api-servlet-jakarta/pom.xml b/magic-api-servlet/magic-api-servlet-jakarta/pom.xml new file mode 100644 index 00000000..be5630f7 --- /dev/null +++ b/magic-api-servlet/magic-api-servlet-jakarta/pom.xml @@ -0,0 +1,40 @@ + + + 4.0.0 + + org.ssssssss + magic-api-servlet + 2.0.2 + + magic-api-servlet-jakarta + jar + magic-api-servlet-jakarta + auto generate http api + + 3.0.4 + + + + jakarta.servlet + jakarta.servlet-api + 6.0.0 + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.10.1 + + 17 + 17 + UTF-8 + + + + + diff --git a/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaCookie.java b/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaCookie.java new file mode 100644 index 00000000..c6fc7ae9 --- /dev/null +++ b/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaCookie.java @@ -0,0 +1,27 @@ +package org.ssssssss.magicapi.servlet.jakarta; + +import jakarta.servlet.http.Cookie; +import org.ssssssss.magicapi.core.servlet.MagicCookie; + +public class MagicJakartaCookie implements MagicCookie { + + private final Cookie cookie; + + public MagicJakartaCookie(Cookie cookie) { + this.cookie = cookie; + } + + @Override + public String getName() { + return cookie.getName(); + } + + @Override + public String getValue() { + return cookie.getValue(); + } + + public Cookie getOriginCookie(){ + return cookie; + } +} diff --git a/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaCorsFilter.java b/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaCorsFilter.java new file mode 100644 index 00000000..a791b831 --- /dev/null +++ b/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaCorsFilter.java @@ -0,0 +1,17 @@ +package org.ssssssss.magicapi.servlet.jakarta; + +import jakarta.servlet.*; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.ssssssss.magicapi.core.config.MagicCorsFilter; + +import java.io.IOException; + +public class MagicJakartaCorsFilter extends MagicCorsFilter implements Filter { + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + super.process(new MagicJakartaHttpServletRequest((HttpServletRequest) request, null), new MagicJakartaHttpServletResponse((HttpServletResponse) response)); + chain.doFilter(request, response); + } +} diff --git a/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaHttpServletRequest.java b/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaHttpServletRequest.java new file mode 100644 index 00000000..cb6c1e51 --- /dev/null +++ b/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaHttpServletRequest.java @@ -0,0 +1,127 @@ +package org.ssssssss.magicapi.servlet.jakarta; + +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.core.MethodParameter; +import org.springframework.http.HttpInputMessage; +import org.springframework.http.server.ServletServerHttpRequest; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; +import org.springframework.web.multipart.MultipartRequest; +import org.springframework.web.multipart.MultipartResolver; +import org.ssssssss.magicapi.core.servlet.MagicCookie; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest; +import org.ssssssss.magicapi.core.servlet.MagicHttpSession; + +import java.io.IOException; +import java.io.InputStream; +import java.security.Principal; +import java.util.Arrays; +import java.util.Enumeration; + +public class MagicJakartaHttpServletRequest implements MagicHttpServletRequest { + + private final HttpServletRequest request; + + private final MultipartResolver multipartResolver; + + public MagicJakartaHttpServletRequest(HttpServletRequest httpServletRequest, MultipartResolver multipartResolver) { + this.request = httpServletRequest; + this.multipartResolver = multipartResolver; + } + + @Override + public String getHeader(String name) { + return request.getHeader(name); + } + + @Override + public Enumeration getHeaders(String name) { + return request.getHeaders(name); + } + + @Override + public String getRequestURI() { + return request.getRequestURI(); + } + + @Override + public String getMethod() { + return request.getMethod(); + } + + @Override + public void setAttribute(String key, Object value) { + request.setAttribute(key, value); + } + + @Override + public String[] getParameterValues(String name) { + return request.getParameterValues(name); + } + + @Override + public Object getAttribute(String name) { + return request.getAttribute(name); + } + + @Override + public HttpInputMessage getHttpInputMessage() { + return new ServletServerHttpRequest(request); + } + + @Override + public String getContentType() { + return request.getContentType(); + } + + @Override + public MagicHttpSession getSession() { + return new MagicJakartaHttpSession(request.getSession()); + } + + @Override + public MagicCookie[] getCookies() { + return Arrays.stream(request.getCookies()).map(MagicJakartaCookie::new).toArray(MagicJakartaCookie[]::new); + } + + @Override + public InputStream getInputStream() throws IOException { + return request.getInputStream(); + } + + @Override + public boolean isMultipart() { + return multipartResolver.isMultipart(request); + } + + @Override + public String getRemoteAddr() { + return request.getRemoteAddr(); + } + + @Override + public MultipartRequest resolveMultipart() { + return multipartResolver.resolveMultipart(request); + } + + @Override + public Principal getUserPrincipal() { + return request.getUserPrincipal(); + } + + + public static class ArgumentsResolver implements HandlerMethodArgumentResolver { + + @Override + public boolean supportsParameter(MethodParameter parameter) { + return parameter.getParameterType() == MagicHttpServletRequest.class; + } + + @Override + public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { + return new MagicJakartaHttpServletRequest(webRequest.getNativeRequest(HttpServletRequest.class), null); + } + } +} diff --git a/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaHttpServletResponse.java b/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaHttpServletResponse.java new file mode 100644 index 00000000..a66b101b --- /dev/null +++ b/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaHttpServletResponse.java @@ -0,0 +1,68 @@ +package org.ssssssss.magicapi.servlet.jakarta; + +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.core.MethodParameter; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; +import org.ssssssss.magicapi.core.servlet.MagicCookie; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletResponse; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Collection; + +public class MagicJakartaHttpServletResponse implements MagicHttpServletResponse { + + private final HttpServletResponse response; + + + public MagicJakartaHttpServletResponse(HttpServletResponse response) { + this.response = response; + } + + @Override + public void setHeader(String name, String value) { + response.setHeader(name, value); + } + + @Override + public void addHeader(String name, String value) { + response.addHeader(name, value); + } + + @Override + public void sendRedirect(String location) throws IOException { + response.sendRedirect(location); + } + + @Override + public void addCookie(MagicCookie cookie) { + MagicJakartaCookie javaEECookie = (MagicJakartaCookie) cookie; + response.addCookie(javaEECookie.getOriginCookie()); + } + + @Override + public OutputStream getOutputStream() throws IOException { + return response.getOutputStream(); + } + + @Override + public Collection getHeaderNames() { + return response.getHeaderNames(); + } + + public static class ArgumentsResolver implements HandlerMethodArgumentResolver { + + @Override + public boolean supportsParameter(MethodParameter parameter) { + return parameter.getParameterType() == MagicHttpServletResponse.class; + } + + @Override + public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { + return new MagicJakartaHttpServletResponse(webRequest.getNativeResponse(HttpServletResponse.class)); + } + } +} diff --git a/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaHttpSession.java b/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaHttpSession.java new file mode 100644 index 00000000..b24b509c --- /dev/null +++ b/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaHttpSession.java @@ -0,0 +1,24 @@ +package org.ssssssss.magicapi.servlet.jakarta; + +import jakarta.servlet.http.HttpSession; +import org.ssssssss.magicapi.core.servlet.MagicHttpSession; + + +public class MagicJakartaHttpSession implements MagicHttpSession { + + private HttpSession session; + + public MagicJakartaHttpSession(HttpSession session) { + this.session = session; + } + + @Override + public Object getAttribute(String key) { + return session.getAttribute(key); + } + + @Override + public void setAttribute(String key, Object value) { + session.setAttribute(key, value); + } +} diff --git a/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaRequestContextHolder.java b/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaRequestContextHolder.java new file mode 100644 index 00000000..b96b377b --- /dev/null +++ b/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaRequestContextHolder.java @@ -0,0 +1,25 @@ +package org.ssssssss.magicapi.servlet.jakarta; + +import org.springframework.web.multipart.MultipartResolver; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletResponse; +import org.ssssssss.magicapi.core.servlet.MagicRequestContextHolder; + +public class MagicJakartaRequestContextHolder implements MagicRequestContextHolder { + + private final MultipartResolver multipartResolver; + + public MagicJakartaRequestContextHolder(MultipartResolver multipartResolver) { + this.multipartResolver = multipartResolver; + } + + @Override + public MagicHttpServletRequest getRequest() { + return convert(servletRequestAttributes -> new MagicJakartaHttpServletRequest(servletRequestAttributes.getRequest(), multipartResolver)); + } + + @Override + public MagicHttpServletResponse getResponse() { + return convert(servletRequestAttributes -> new MagicJakartaHttpServletResponse(servletRequestAttributes.getResponse())); + } +} diff --git a/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaResponseExtension.java b/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaResponseExtension.java new file mode 100644 index 00000000..dd3a51ce --- /dev/null +++ b/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaResponseExtension.java @@ -0,0 +1,104 @@ +package org.ssssssss.magicapi.servlet.jakarta; + +import jakarta.servlet.http.Cookie; +import org.apache.commons.lang3.StringUtils; +import org.ssssssss.magicapi.core.context.RequestContext; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletResponse; +import org.ssssssss.magicapi.modules.servlet.ResponseModule; +import org.ssssssss.script.annotation.Comment; +import org.ssssssss.script.functions.ExtensionMethod; +import org.ssssssss.script.functions.ObjectConvertExtension; + +import java.util.Map; + +public class MagicJakartaResponseExtension implements ExtensionMethod { + + /** + * 添加cookie + */ + @Comment("添加Cookie") + public ResponseModule addCookie(ResponseModule module, @Comment(name = "cookie", value = "Cookie对象") Cookie cookie) { + if (cookie != null) { + MagicHttpServletResponse response = RequestContext.getHttpServletResponse(); + if (response != null) { + response.addCookie(new MagicJakartaCookie(cookie)); + } + } + return module; + } + + /** + * 批量添加cookie + */ + @Comment("批量添加Cookie") + public ResponseModule addCookies(ResponseModule module, @Comment(name = "cookies", value = "Cookies") Map cookies) { + return addCookies(module, cookies, null); + + } + + /** + * 添加cookie + */ + @Comment("添加Cookie") + public ResponseModule addCookie(ResponseModule module, @Comment(name = "name", value = "Cookie名") String name, + @Comment(name = "value", value = "Cookie值") String value, + @Comment(name = "options", value = "Cookie选项,如`path`、`httpOnly`、`domain`、`maxAge`") Map options) { + if (StringUtils.isNotBlank(name)) { + Cookie cookie = new Cookie(name, value); + if (options != null) { + Object path = options.get("path"); + if (path != null) { + cookie.setPath(path.toString()); + } + Object httpOnly = options.get("httpOnly"); + if (httpOnly != null) { + cookie.setHttpOnly("true".equalsIgnoreCase(httpOnly.toString())); + } + Object domain = options.get("domain"); + if (domain != null) { + cookie.setDomain(domain.toString()); + } + Object maxAge = options.get("maxAge"); + int age; + if (maxAge != null && (age = ObjectConvertExtension.asInt(maxAge, Integer.MIN_VALUE)) != Integer.MIN_VALUE) { + cookie.setMaxAge(age); + } + } + addCookie(module, cookie); + } + return module; + } + + + /** + * 添加cookie + */ + @Comment("添加Cookie") + public ResponseModule addCookie(ResponseModule module, @Comment(name = "name", value = "cookie名") String name, + @Comment(name = "value", value = "cookie值") String value) { + if (StringUtils.isNotBlank(name)) { + addCookie(module, new Cookie(name, value)); + } + return module; + } + + /** + * 批量添加cookie + */ + @Comment("批量添加Cookie") + public ResponseModule addCookies(ResponseModule module, + @Comment(name = "cookies", value = "Cookies") Map cookies, + @Comment(name = "options", value = "Cookie选项,如`path`、`httpOnly`、`domain`、`maxAge`") Map options) { + if (cookies != null) { + for (Map.Entry entry : cookies.entrySet()) { + addCookie(module, entry.getKey(), entry.getValue(), options); + } + } + return module; + } + + @Override + public Class support() { + return ResponseModule.class; + } +} diff --git a/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaServletConfiguration.java b/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaServletConfiguration.java new file mode 100644 index 00000000..6e8fde34 --- /dev/null +++ b/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaServletConfiguration.java @@ -0,0 +1,69 @@ +package org.ssssssss.magicapi.servlet.jakarta; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.multipart.MultipartResolver; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.ssssssss.magicapi.core.config.MagicAPIProperties; +import org.ssssssss.magicapi.core.interceptor.AuthorizationInterceptor; +import org.ssssssss.magicapi.core.servlet.MagicRequestContextHolder; + +import java.util.List; + +@Configuration +public class MagicJakartaServletConfiguration implements WebMvcConfigurer { + + private final MagicAPIProperties properties; + + private final MagicJakartaCorsFilter magicCorsFilter = new MagicJakartaCorsFilter(); + + private final ObjectProvider magicWebRequestInterceptorProvider; + + public MagicJakartaServletConfiguration(MagicAPIProperties properties, ObjectProvider magicWebRequestInterceptorProvider) { + this.properties = properties; + this.magicWebRequestInterceptorProvider = magicWebRequestInterceptorProvider; + } + + @Bean + public MagicRequestContextHolder magicRequestContextHolder(MultipartResolver multipartResolver){ + return new MagicJakartaRequestContextHolder(multipartResolver); + } + + @Bean + public MagicJakartaWebRequestInterceptor magicWebRequestInterceptor(AuthorizationInterceptor authorizationInterceptor){ + return new MagicJakartaWebRequestInterceptor(properties.isSupportCrossDomain() ? magicCorsFilter : null, authorizationInterceptor); + } + + @Bean + public MagicJakartaResponseExtension magicJakartaResponseExtension() { + return new MagicJakartaResponseExtension(); + } + + + @Override + public void addArgumentResolvers(List resolvers) { + resolvers.add(new MagicJakartaHttpServletRequest.ArgumentsResolver()); + resolvers.add(new MagicJakartaHttpServletResponse.ArgumentsResolver()); + } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(magicWebRequestInterceptorProvider.getObject()).addPathPatterns("/**"); + } + + @Bean + @ConditionalOnProperty(prefix = "magic-api", value = "support-cross-domain", havingValue = "true", matchIfMissing = true) + public FilterRegistrationBean magicCorsFilterRegistrationBean() { + FilterRegistrationBean registration = new FilterRegistrationBean<>(magicCorsFilter); + registration.addUrlPatterns("/*"); + registration.setName("Magic Cors Filter"); + registration.setOrder(Ordered.HIGHEST_PRECEDENCE); + return registration; + } +} diff --git a/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaWebRequestInterceptor.java b/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaWebRequestInterceptor.java new file mode 100644 index 00000000..e4e27636 --- /dev/null +++ b/magic-api-servlet/magic-api-servlet-jakarta/src/main/java/org/ssssssss/magicapi/servlet/jakarta/MagicJakartaWebRequestInterceptor.java @@ -0,0 +1,23 @@ +package org.ssssssss.magicapi.servlet.jakarta; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.web.servlet.HandlerInterceptor; +import org.ssssssss.magicapi.core.config.MagicCorsFilter; +import org.ssssssss.magicapi.core.interceptor.AuthorizationInterceptor; +import org.ssssssss.magicapi.core.interceptor.MagicWebRequestInterceptor; + + +public class MagicJakartaWebRequestInterceptor extends MagicWebRequestInterceptor implements HandlerInterceptor { + + + public MagicJakartaWebRequestInterceptor(MagicCorsFilter magicCorsFilter, AuthorizationInterceptor authorizationInterceptor) { + super(magicCorsFilter, authorizationInterceptor); + } + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + super.handle(handler, new MagicJakartaHttpServletRequest(request, null), new MagicJakartaHttpServletResponse(response)); + return true; + } +} diff --git a/magic-api-servlet/magic-api-servlet-javaee/pom.xml b/magic-api-servlet/magic-api-servlet-javaee/pom.xml new file mode 100644 index 00000000..049d89ce --- /dev/null +++ b/magic-api-servlet/magic-api-servlet-javaee/pom.xml @@ -0,0 +1,18 @@ + + + 4.0.0 + + org.ssssssss + magic-api-servlet + 2.0.2 + + magic-api-servlet-javaee + jar + magic-api-servlet-javaee + auto generate http api + + + + diff --git a/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEECookie.java b/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEECookie.java new file mode 100644 index 00000000..52a81746 --- /dev/null +++ b/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEECookie.java @@ -0,0 +1,28 @@ +package org.ssssssss.magicapi.servlet.javaee; + +import org.ssssssss.magicapi.core.servlet.MagicCookie; + +import javax.servlet.http.Cookie; + +public class MagicJavaEECookie implements MagicCookie { + + private final Cookie cookie; + + public MagicJavaEECookie(Cookie cookie) { + this.cookie = cookie; + } + + @Override + public String getName() { + return cookie.getName(); + } + + @Override + public String getValue() { + return cookie.getValue(); + } + + public Cookie getOriginCookie() { + return cookie; + } +} diff --git a/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEECorsFilter.java b/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEECorsFilter.java new file mode 100644 index 00000000..05dea150 --- /dev/null +++ b/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEECorsFilter.java @@ -0,0 +1,17 @@ +package org.ssssssss.magicapi.servlet.javaee; + +import org.ssssssss.magicapi.core.config.MagicCorsFilter; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class MagicJavaEECorsFilter extends MagicCorsFilter implements Filter { + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + super.process(new MagicJavaEEHttpServletRequest((HttpServletRequest) request, null), new MagicJavaEEHttpServletResponse((HttpServletResponse) response)); + chain.doFilter(request, response); + } +} diff --git a/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEEHttpServletRequest.java b/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEEHttpServletRequest.java new file mode 100644 index 00000000..ef6e4eb8 --- /dev/null +++ b/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEEHttpServletRequest.java @@ -0,0 +1,126 @@ +package org.ssssssss.magicapi.servlet.javaee; + +import org.springframework.core.MethodParameter; +import org.springframework.http.HttpInputMessage; +import org.springframework.http.server.ServletServerHttpRequest; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; +import org.springframework.web.multipart.MultipartRequest; +import org.springframework.web.multipart.MultipartResolver; +import org.ssssssss.magicapi.core.servlet.MagicCookie; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest; +import org.ssssssss.magicapi.core.servlet.MagicHttpSession; + +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.io.InputStream; +import java.security.Principal; +import java.util.Arrays; +import java.util.Enumeration; + +public class MagicJavaEEHttpServletRequest implements MagicHttpServletRequest { + + private final HttpServletRequest request; + + private final MultipartResolver multipartResolver; + + public MagicJavaEEHttpServletRequest(HttpServletRequest request, MultipartResolver multipartResolver) { + this.request = request; + this.multipartResolver = multipartResolver; + } + + @Override + public String getHeader(String name) { + return request.getHeader(name); + } + + @Override + public Enumeration getHeaders(String name) { + return request.getHeaders(name); + } + + @Override + public String getRequestURI() { + return request.getRequestURI(); + } + + @Override + public String getMethod() { + return request.getMethod(); + } + + @Override + public void setAttribute(String key, Object value) { + request.setAttribute(key, value); + } + + @Override + public String[] getParameterValues(String name) { + return request.getParameterValues(name); + } + + @Override + public Object getAttribute(String name) { + return request.getAttribute(name); + } + + @Override + public HttpInputMessage getHttpInputMessage() { + return new ServletServerHttpRequest(request); + } + + @Override + public String getContentType() { + return request.getContentType(); + } + + @Override + public MagicHttpSession getSession() { + return new MagicJavaEEHttpSession(request.getSession()); + } + + @Override + public MagicCookie[] getCookies() { + return Arrays.stream(request.getCookies()).map(MagicJavaEECookie::new).toArray(MagicJavaEECookie[]::new); + } + + @Override + public InputStream getInputStream() throws IOException { + return request.getInputStream(); + } + + @Override + public boolean isMultipart() { + return multipartResolver.isMultipart(request); + } + + @Override + public String getRemoteAddr() { + return request.getRemoteAddr(); + } + + @Override + public MultipartRequest resolveMultipart() { + return multipartResolver.resolveMultipart(request); + } + + @Override + public Principal getUserPrincipal() { + return request.getUserPrincipal(); + } + + public static class ArgumentsResolver implements HandlerMethodArgumentResolver { + + @Override + public boolean supportsParameter(MethodParameter parameter) { + return parameter.getParameterType() == MagicHttpServletRequest.class; + } + + @Override + public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { + return new MagicJavaEEHttpServletRequest(webRequest.getNativeRequest(HttpServletRequest.class), null); + } + } +} diff --git a/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEEHttpServletResponse.java b/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEEHttpServletResponse.java new file mode 100644 index 00000000..04b4ce79 --- /dev/null +++ b/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEEHttpServletResponse.java @@ -0,0 +1,69 @@ +package org.ssssssss.magicapi.servlet.javaee; + +import org.springframework.core.MethodParameter; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; +import org.ssssssss.magicapi.core.servlet.MagicCookie; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletResponse; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Collection; + +public class MagicJavaEEHttpServletResponse implements MagicHttpServletResponse { + + private final HttpServletResponse response; + + + public MagicJavaEEHttpServletResponse(HttpServletResponse response) { + this.response = response; + } + + @Override + public void setHeader(String name, String value) { + response.setHeader(name, value); + } + + @Override + public void addHeader(String name, String value) { + response.addHeader(name, value); + } + + @Override + public void sendRedirect(String location) throws IOException { + response.sendRedirect(location); + } + + @Override + public void addCookie(MagicCookie cookie) { + MagicJavaEECookie javaEECookie = (MagicJavaEECookie) cookie; + response.addCookie(javaEECookie.getOriginCookie()); + } + + @Override + public OutputStream getOutputStream() throws IOException { + return response.getOutputStream(); + } + + @Override + public Collection getHeaderNames() { + return response.getHeaderNames(); + } + + + public static class ArgumentsResolver implements HandlerMethodArgumentResolver { + + @Override + public boolean supportsParameter(MethodParameter parameter) { + return parameter.getParameterType() == MagicHttpServletResponse.class; + } + + @Override + public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { + return new MagicJavaEEHttpServletResponse(webRequest.getNativeResponse(HttpServletResponse.class)); + } + } +} diff --git a/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEEHttpSession.java b/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEEHttpSession.java new file mode 100644 index 00000000..a64d03d0 --- /dev/null +++ b/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEEHttpSession.java @@ -0,0 +1,24 @@ +package org.ssssssss.magicapi.servlet.javaee; + +import org.ssssssss.magicapi.core.servlet.MagicHttpSession; + +import javax.servlet.http.HttpSession; + +public class MagicJavaEEHttpSession implements MagicHttpSession { + + private HttpSession session; + + public MagicJavaEEHttpSession(HttpSession session) { + this.session = session; + } + + @Override + public Object getAttribute(String key) { + return session.getAttribute(key); + } + + @Override + public void setAttribute(String key, Object value) { + session.setAttribute(key, value); + } +} diff --git a/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEERequestContextHolder.java b/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEERequestContextHolder.java new file mode 100644 index 00000000..a6131d68 --- /dev/null +++ b/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEERequestContextHolder.java @@ -0,0 +1,25 @@ +package org.ssssssss.magicapi.servlet.javaee; + +import org.springframework.web.multipart.MultipartResolver; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletResponse; +import org.ssssssss.magicapi.core.servlet.MagicRequestContextHolder; + +public class MagicJavaEERequestContextHolder implements MagicRequestContextHolder { + + private final MultipartResolver multipartResolver; + + public MagicJavaEERequestContextHolder(MultipartResolver multipartResolver) { + this.multipartResolver = multipartResolver; + } + + @Override + public MagicHttpServletRequest getRequest() { + return convert(servletRequestAttributes -> new MagicJavaEEHttpServletRequest(servletRequestAttributes.getRequest(), multipartResolver)); + } + + @Override + public MagicHttpServletResponse getResponse() { + return convert(servletRequestAttributes -> new MagicJavaEEHttpServletResponse(servletRequestAttributes.getResponse())); + } +} diff --git a/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEEResponseExtension.java b/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEEResponseExtension.java new file mode 100644 index 00000000..1e9b4005 --- /dev/null +++ b/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEEResponseExtension.java @@ -0,0 +1,104 @@ +package org.ssssssss.magicapi.servlet.javaee; + +import org.apache.commons.lang3.StringUtils; +import org.ssssssss.magicapi.core.context.RequestContext; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletResponse; +import org.ssssssss.magicapi.modules.servlet.ResponseModule; +import org.ssssssss.script.annotation.Comment; +import org.ssssssss.script.functions.ExtensionMethod; +import org.ssssssss.script.functions.ObjectConvertExtension; + +import javax.servlet.http.Cookie; +import java.util.Map; + +public class MagicJavaEEResponseExtension implements ExtensionMethod { + + /** + * 添加cookie + */ + @Comment("添加Cookie") + public ResponseModule addCookie(ResponseModule module, @Comment(name = "cookie", value = "Cookie对象") Cookie cookie) { + if (cookie != null) { + MagicHttpServletResponse response = RequestContext.getHttpServletResponse(); + if (response != null) { + response.addCookie(new MagicJavaEECookie(cookie)); + } + } + return module; + } + + /** + * 批量添加cookie + */ + @Comment("批量添加Cookie") + public ResponseModule addCookies(ResponseModule module, @Comment(name = "cookies", value = "Cookies") Map cookies) { + return addCookies(module, cookies, null); + + } + + /** + * 添加cookie + */ + @Comment("添加Cookie") + public ResponseModule addCookie(ResponseModule module, @Comment(name = "name", value = "Cookie名") String name, + @Comment(name = "value", value = "Cookie值") String value, + @Comment(name = "options", value = "Cookie选项,如`path`、`httpOnly`、`domain`、`maxAge`") Map options) { + if (StringUtils.isNotBlank(name)) { + Cookie cookie = new Cookie(name, value); + if (options != null) { + Object path = options.get("path"); + if (path != null) { + cookie.setPath(path.toString()); + } + Object httpOnly = options.get("httpOnly"); + if (httpOnly != null) { + cookie.setHttpOnly("true".equalsIgnoreCase(httpOnly.toString())); + } + Object domain = options.get("domain"); + if (domain != null) { + cookie.setDomain(domain.toString()); + } + Object maxAge = options.get("maxAge"); + int age; + if (maxAge != null && (age = ObjectConvertExtension.asInt(maxAge, Integer.MIN_VALUE)) != Integer.MIN_VALUE) { + cookie.setMaxAge(age); + } + } + addCookie(module, cookie); + } + return module; + } + + + /** + * 添加cookie + */ + @Comment("添加Cookie") + public ResponseModule addCookie(ResponseModule module, @Comment(name = "name", value = "cookie名") String name, + @Comment(name = "value", value = "cookie值") String value) { + if (StringUtils.isNotBlank(name)) { + addCookie(module, new Cookie(name, value)); + } + return module; + } + + /** + * 批量添加cookie + */ + @Comment("批量添加Cookie") + public ResponseModule addCookies(ResponseModule module, + @Comment(name = "cookies", value = "Cookies") Map cookies, + @Comment(name = "options", value = "Cookie选项,如`path`、`httpOnly`、`domain`、`maxAge`") Map options) { + if (cookies != null) { + for (Map.Entry entry : cookies.entrySet()) { + addCookie(module, entry.getKey(), entry.getValue(), options); + } + } + return module; + } + + @Override + public Class support() { + return ResponseModule.class; + } +} diff --git a/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEEServletConfiguration.java b/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEEServletConfiguration.java new file mode 100644 index 00000000..c11f33e1 --- /dev/null +++ b/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEEServletConfiguration.java @@ -0,0 +1,69 @@ +package org.ssssssss.magicapi.servlet.javaee; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.multipart.MultipartResolver; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.ssssssss.magicapi.core.config.MagicAPIProperties; +import org.ssssssss.magicapi.core.interceptor.AuthorizationInterceptor; +import org.ssssssss.magicapi.core.servlet.MagicRequestContextHolder; + +import java.util.List; + +@Configuration +public class MagicJavaEEServletConfiguration implements WebMvcConfigurer { + + private final MagicAPIProperties properties; + + private final ObjectProvider magicWebRequestInterceptorProvider; + + + public MagicJavaEEServletConfiguration(MagicAPIProperties properties, ObjectProvider magicWebRequestInterceptorProvider) { + this.properties = properties; + this.magicWebRequestInterceptorProvider = magicWebRequestInterceptorProvider; + } + + private MagicJavaEECorsFilter magicCorsFilter = new MagicJavaEECorsFilter(); + + @Bean + public MagicRequestContextHolder magicRequestContextHolder(MultipartResolver multipartResolver){ + return new MagicJavaEERequestContextHolder(multipartResolver); + } + + @Bean + public MagicJavaEEWebRequestInterceptor magicWebRequestInterceptor(AuthorizationInterceptor authorizationInterceptor){ + return new MagicJavaEEWebRequestInterceptor(properties.isSupportCrossDomain() ? magicCorsFilter : null, authorizationInterceptor); + } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(magicWebRequestInterceptorProvider.getObject()).addPathPatterns("/**"); + } + + @Override + public void addArgumentResolvers(List resolvers) { + resolvers.add(new MagicJavaEEHttpServletRequest.ArgumentsResolver()); + resolvers.add(new MagicJavaEEHttpServletResponse.ArgumentsResolver()); + } + + @Bean + public MagicJavaEEResponseExtension magicJavaEEResponseExtension() { + return new MagicJavaEEResponseExtension(); + } + + @Bean + @ConditionalOnProperty(prefix = "magic-api", value = "support-cross-domain", havingValue = "true", matchIfMissing = true) + public FilterRegistrationBean magicCorsFilterRegistrationBean() { + FilterRegistrationBean registration = new FilterRegistrationBean<>(magicCorsFilter); + registration.addUrlPatterns("/*"); + registration.setName("Magic Cors Filter"); + registration.setOrder(Ordered.HIGHEST_PRECEDENCE); + return registration; + } +} diff --git a/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEEWebRequestInterceptor.java b/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEEWebRequestInterceptor.java new file mode 100644 index 00000000..fb9354ce --- /dev/null +++ b/magic-api-servlet/magic-api-servlet-javaee/src/main/java/org/ssssssss/magicapi/servlet/javaee/MagicJavaEEWebRequestInterceptor.java @@ -0,0 +1,23 @@ +package org.ssssssss.magicapi.servlet.javaee; + +import org.springframework.web.servlet.HandlerInterceptor; +import org.ssssssss.magicapi.core.config.MagicCorsFilter; +import org.ssssssss.magicapi.core.interceptor.AuthorizationInterceptor; +import org.ssssssss.magicapi.core.interceptor.MagicWebRequestInterceptor; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class MagicJavaEEWebRequestInterceptor extends MagicWebRequestInterceptor implements HandlerInterceptor { + + + public MagicJavaEEWebRequestInterceptor(MagicCorsFilter magicCorsFilter, AuthorizationInterceptor authorizationInterceptor) { + super(magicCorsFilter, authorizationInterceptor); + } + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + super.handle(handler, new MagicJavaEEHttpServletRequest(request, null), new MagicJavaEEHttpServletResponse(response)); + return true; + } +} diff --git a/magic-api-servlet/pom.xml b/magic-api-servlet/pom.xml new file mode 100644 index 00000000..a779db8f --- /dev/null +++ b/magic-api-servlet/pom.xml @@ -0,0 +1,25 @@ + + + 4.0.0 + + org.ssssssss + magic-api-parent + 2.0.2 + + magic-api-servlet + pom + magic-api-servlet + auto generate http api + + magic-api-servlet-jakarta + magic-api-servlet-javaee + + + + org.ssssssss + magic-api + + + diff --git a/magic-api-spring-boot-starter/pom.xml b/magic-api-spring-boot-starter/pom.xml index 479dbf23..3af6cd65 100644 --- a/magic-api-spring-boot-starter/pom.xml +++ b/magic-api-spring-boot-starter/pom.xml @@ -41,5 +41,13 @@ spring-boot-configuration-processor true + + org.ssssssss + magic-api-servlet-jakarta + + + org.ssssssss + magic-api-servlet-javaee + diff --git a/magic-api-spring-boot-starter/src/main/java/org/ssssssss/magicapi/spring/boot/starter/MagicAPIAutoConfiguration.java b/magic-api-spring-boot-starter/src/main/java/org/ssssssss/magicapi/spring/boot/starter/MagicAPIAutoConfiguration.java index 9499f54c..fb9681c0 100644 --- a/magic-api-spring-boot-starter/src/main/java/org/ssssssss/magicapi/spring/boot/starter/MagicAPIAutoConfiguration.java +++ b/magic-api-spring-boot-starter/src/main/java/org/ssssssss/magicapi/spring/boot/starter/MagicAPIAutoConfiguration.java @@ -10,19 +10,16 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Lazy; -import org.springframework.core.Ordered; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; @@ -40,7 +37,10 @@ import org.ssssssss.magicapi.core.handler.MagicCoordinationHandler; import org.ssssssss.magicapi.core.handler.MagicDebugHandler; import org.ssssssss.magicapi.core.handler.MagicWebSocketDispatcher; import org.ssssssss.magicapi.core.handler.MagicWorkbenchHandler; -import org.ssssssss.magicapi.core.interceptor.*; +import org.ssssssss.magicapi.core.interceptor.AuthorizationInterceptor; +import org.ssssssss.magicapi.core.interceptor.DefaultAuthorizationInterceptor; +import org.ssssssss.magicapi.core.interceptor.RequestInterceptor; +import org.ssssssss.magicapi.core.interceptor.ResultProvider; import org.ssssssss.magicapi.core.logging.LoggerManager; import org.ssssssss.magicapi.core.model.DataType; import org.ssssssss.magicapi.core.model.MagicEntity; @@ -51,6 +51,7 @@ import org.ssssssss.magicapi.core.service.*; import org.ssssssss.magicapi.core.service.impl.DefaultMagicAPIService; import org.ssssssss.magicapi.core.service.impl.DefaultMagicResourceService; import org.ssssssss.magicapi.core.service.impl.RequestMagicDynamicRegistry; +import org.ssssssss.magicapi.core.servlet.MagicRequestContextHolder; import org.ssssssss.magicapi.core.web.MagicResourceController; import org.ssssssss.magicapi.core.web.MagicWorkbenchController; import org.ssssssss.magicapi.core.web.RequestHandler; @@ -61,6 +62,7 @@ import org.ssssssss.magicapi.function.service.FunctionMagicDynamicRegistry; import org.ssssssss.magicapi.jsr223.LanguageProvider; import org.ssssssss.magicapi.modules.DynamicModule; import org.ssssssss.magicapi.utils.Mapping; +import org.ssssssss.magicapi.utils.WebUtils; import org.ssssssss.script.MagicResourceLoader; import org.ssssssss.script.MagicScript; import org.ssssssss.script.MagicScriptEngine; @@ -85,7 +87,7 @@ import java.util.stream.Collectors; @Configuration @ConditionalOnClass({RequestMappingHandlerMapping.class}) @EnableConfigurationProperties(MagicAPIProperties.class) -@Import({MagicJsonAutoConfiguration.class, ApplicationUriPrinter.class, MagicModuleConfiguration.class, MagicDynamicRegistryConfiguration.class}) +@Import({MagicServletConfiguration.class, MagicJsonAutoConfiguration.class, ApplicationUriPrinter.class, MagicModuleConfiguration.class, MagicDynamicRegistryConfiguration.class}) @EnableWebSocket @AutoConfigureAfter(MagicPluginConfiguration.class) public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketConfigurer { @@ -126,24 +128,18 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon private final ObjectProvider dataSourceEncryptProvider; - private final MagicCorsFilter magicCorsFilter = new MagicCorsFilter(); - private final MagicAPIProperties properties; private final ApplicationContext applicationContext; private boolean registerMapping = false; - private boolean registerInterceptor = false; - private boolean registerWebsocket = false; @Autowired @Lazy private RequestMappingHandlerMapping requestMappingHandlerMapping; - private DefaultAuthorizationInterceptor defaultAuthorizationInterceptor; - public MagicAPIAutoConfiguration(MagicAPIProperties properties, ObjectProvider> requestInterceptorsProvider, ObjectProvider> extensionMethodsProvider, @@ -212,25 +208,6 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon } } - @Override - public void addInterceptors(InterceptorRegistry registry) { - if (!registerInterceptor) { - registerInterceptor = true; - registry.addInterceptor(new MagicWebRequestInterceptor(properties.isSupportCrossDomain() ? magicCorsFilter : null, authorizationInterceptorProvider.getIfAvailable(this::createAuthorizationInterceptor))) - .addPathPatterns("/**"); - } - } - - @Bean - @ConditionalOnProperty(prefix = "magic-api", value = "support-cross-domain", havingValue = "true", matchIfMissing = true) - public FilterRegistrationBean magicCorsFilterRegistrationBean() { - FilterRegistrationBean registration = new FilterRegistrationBean<>(magicCorsFilter); - registration.addUrlPatterns("/*"); - registration.setName("Magic Cors Filter"); - registration.setOrder(Ordered.HIGHEST_PRECEDENCE); - return registration; - } - @Bean @ConditionalOnMissingBean public MagicResourceService magicResourceService(org.ssssssss.magicapi.core.resource.Resource workspace) { @@ -251,8 +228,9 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon */ @Bean @ConditionalOnMissingBean - public MagicAPIService magicAPIService(ResultProvider resultProvider, MagicResourceService magicResourceService, RequestMagicDynamicRegistry requestMagicDynamicRegistry, FunctionMagicDynamicRegistry functionMagicDynamicRegistry) { - return new DefaultMagicAPIService(resultProvider, properties.getInstanceId(), magicResourceService, requestMagicDynamicRegistry, functionMagicDynamicRegistry, properties.isThrowException(), properties.getPrefix() ,applicationContext); + public MagicAPIService magicAPIService(ResultProvider resultProvider, MagicResourceService magicResourceService, MagicRequestContextHolder magicRequestContextHolder, RequestMagicDynamicRegistry requestMagicDynamicRegistry, FunctionMagicDynamicRegistry functionMagicDynamicRegistry) { + WebUtils.magicRequestContextHolder = magicRequestContextHolder; + return new DefaultMagicAPIService(resultProvider, properties.getInstanceId(), magicResourceService, requestMagicDynamicRegistry, functionMagicDynamicRegistry, properties.isThrowException(), properties.getPrefix() ,magicRequestContextHolder, applicationContext); } /** @@ -346,7 +324,7 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon configuration.setThrowException(properties.isThrowException()); configuration.setEditorConfig(properties.getEditorConfig()); configuration.setWorkspace(magicResource); - configuration.setAuthorizationInterceptor(authorizationInterceptorProvider.getIfAvailable(this::createAuthorizationInterceptor)); + configuration.setAuthorizationInterceptor(authorizationInterceptorProvider.getObject()); // 注册函数 this.magicFunctionsProvider.getIfAvailable(Collections::emptyList).forEach(JavaReflection::registerFunction); // 向页面传递配置信息时不传递用户名密码,增强安全性 @@ -401,13 +379,11 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon return configuration; } - public AuthorizationInterceptor createAuthorizationInterceptor() { - if (defaultAuthorizationInterceptor != null) { - return defaultAuthorizationInterceptor; - } + @Bean + @ConditionalOnMissingBean + public AuthorizationInterceptor authorizationInterceptor(MagicAPIProperties properties){ Security security = properties.getSecurity(); - defaultAuthorizationInterceptor = new DefaultAuthorizationInterceptor(security.getUsername(), security.getPassword()); - return defaultAuthorizationInterceptor; + return new DefaultAuthorizationInterceptor(security.getUsername(), security.getPassword()); } @Override @@ -420,7 +396,7 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon MagicWebSocketDispatcher dispatcher = new MagicWebSocketDispatcher(properties.getInstanceId(), magicNotifyService, Arrays.asList( new MagicDebugHandler(), new MagicCoordinationHandler(), - new MagicWorkbenchHandler(authorizationInterceptorProvider.getIfAvailable(this::createAuthorizationInterceptor)) + new MagicWorkbenchHandler(authorizationInterceptorProvider.getObject()) )); WebSocketHandlerRegistration registration = webSocketHandlerRegistry.addHandler(dispatcher, web + "/console"); if (properties.isSupportCrossDomain()) { diff --git a/magic-api-spring-boot-starter/src/main/java/org/ssssssss/magicapi/spring/boot/starter/MagicModuleConfiguration.java b/magic-api-spring-boot-starter/src/main/java/org/ssssssss/magicapi/spring/boot/starter/MagicModuleConfiguration.java index 4b34371d..44311142 100644 --- a/magic-api-spring-boot-starter/src/main/java/org/ssssssss/magicapi/spring/boot/starter/MagicModuleConfiguration.java +++ b/magic-api-spring-boot-starter/src/main/java/org/ssssssss/magicapi/spring/boot/starter/MagicModuleConfiguration.java @@ -17,6 +17,7 @@ import org.ssssssss.magicapi.core.config.MagicAPIProperties; import org.ssssssss.magicapi.core.config.Page; import org.ssssssss.magicapi.core.interceptor.DefaultResultProvider; import org.ssssssss.magicapi.core.interceptor.ResultProvider; +import org.ssssssss.magicapi.core.servlet.MagicRequestContextHolder; import org.ssssssss.magicapi.datasource.model.MagicDynamicDataSource; import org.ssssssss.magicapi.jsr223.JSR223LanguageProvider; import org.ssssssss.magicapi.modules.db.ColumnMapperAdapter; @@ -177,8 +178,8 @@ public class MagicModuleConfiguration { @Bean @ConditionalOnMissingBean - public RequestModule magicRequestModule(){ - return new RequestModule(multipartResolver); + public RequestModule magicRequestModule(MagicRequestContextHolder magicRequestContextHolder){ + return new RequestModule(magicRequestContextHolder); } /** diff --git a/magic-api-spring-boot-starter/src/main/java/org/ssssssss/magicapi/spring/boot/starter/MagicServletConfiguration.java b/magic-api-spring-boot-starter/src/main/java/org/ssssssss/magicapi/spring/boot/starter/MagicServletConfiguration.java new file mode 100644 index 00000000..15ac2f75 --- /dev/null +++ b/magic-api-spring-boot-starter/src/main/java/org/ssssssss/magicapi/spring/boot/starter/MagicServletConfiguration.java @@ -0,0 +1,40 @@ +package org.ssssssss.magicapi.spring.boot.starter; + +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.ImportSelector; +import org.springframework.core.type.AnnotationMetadata; +import org.ssssssss.magicapi.servlet.javaee.MagicJavaEEServletConfiguration; + +@Configuration +@AutoConfigureBefore(MagicAPIAutoConfiguration.class) +public class MagicServletConfiguration { + + public MagicServletConfiguration() { + } + + static class JakartaConfigurationImportSelector implements ImportSelector { + + @Override + public String[] selectImports(AnnotationMetadata importingClassMetadata) { + return new String[]{"org.ssssssss.magicapi.servlet.jakarta.MagicJakartaServletConfiguration"}; + } + } + + @Configuration + @ConditionalOnClass(name = "jakarta.servlet.http.HttpServletRequest") + @Import(JakartaConfigurationImportSelector.class) + static class JakartaEEConfiguration { + + + } + + @Configuration + @ConditionalOnClass(name = "javax.servlet.http.HttpServletRequest") + @Import(MagicJavaEEServletConfiguration.class) + static class JavaEEConfiguration{ + + } +} diff --git a/magic-api-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/magic-api-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..79be26f4 --- /dev/null +++ b/magic-api-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.ssssssss.magicapi.spring.boot.starter.MagicAPIAutoConfiguration \ No newline at end of file diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/core/config/MagicCorsFilter.java b/magic-api/src/main/java/org/ssssssss/magicapi/core/config/MagicCorsFilter.java index 911cb687..66412b3b 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/core/config/MagicCorsFilter.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/core/config/MagicCorsFilter.java @@ -2,42 +2,22 @@ package org.ssssssss.magicapi.core.config; import org.apache.commons.lang3.StringUtils; import org.springframework.http.HttpHeaders; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletResponse; -import javax.servlet.*; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; +public abstract class MagicCorsFilter { -public class MagicCorsFilter implements Filter { - - @Override - public void init(FilterConfig filterConfig) { - - } - - @Override - public void destroy() { - - } - - public void process(HttpServletRequest request, HttpServletResponse response) { - String value = request.getHeader(HttpHeaders.ORIGIN); - response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, StringUtils.isBlank(value) ? "*" : value); - response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, Constants.CONST_STRING_TRUE); - value = request.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS); - if (StringUtils.isNotBlank(value)) { - response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, value); - } - value = request.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD); - response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, StringUtils.isBlank(value) ? "GET,POST,OPTIONS,PUT,DELETE" : value); - } - - @Override - public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { - HttpServletRequest request = (HttpServletRequest) req; + public void process(MagicHttpServletRequest request, MagicHttpServletResponse response) { if (StringUtils.isNotBlank(Constants.HEADER_REQUEST_CLIENT_ID)) { - process(request, (HttpServletResponse) resp); + String value = request.getHeader(HttpHeaders.ORIGIN); + response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, StringUtils.isBlank(value) ? "*" : value); + response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, Constants.CONST_STRING_TRUE); + value = request.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS); + if (StringUtils.isNotBlank(value)) { + response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, value); + } + value = request.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD); + response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, StringUtils.isBlank(value) ? "GET,POST,OPTIONS,PUT,DELETE" : value); } - chain.doFilter(req, resp); } } diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/core/context/CookieContext.java b/magic-api/src/main/java/org/ssssssss/magicapi/core/context/CookieContext.java index 68e1faf2..cebf35d9 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/core/context/CookieContext.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/core/context/CookieContext.java @@ -1,7 +1,8 @@ package org.ssssssss.magicapi.core.context; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; +import org.ssssssss.magicapi.core.servlet.MagicCookie; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest; + import java.util.HashMap; /** @@ -11,16 +12,16 @@ import java.util.HashMap; */ public class CookieContext extends HashMap { - private final Cookie[] cookies; + private final MagicCookie[] cookies; - public CookieContext(HttpServletRequest request) { - this.cookies = request.getCookies(); + public CookieContext(MagicHttpServletRequest request) { + this.cookies = request.getCookies(); } @Override public String get(Object key) { if (cookies != null) { - for (Cookie cookie : cookies) { + for (MagicCookie cookie : cookies) { if (cookie.getName().equalsIgnoreCase("" + key)) { return cookie.getValue(); } diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/core/context/RequestContext.java b/magic-api/src/main/java/org/ssssssss/magicapi/core/context/RequestContext.java index 2b5dcbea..5e16be34 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/core/context/RequestContext.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/core/context/RequestContext.java @@ -1,7 +1,8 @@ package org.ssssssss.magicapi.core.context; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletResponse; + /** * 请求上下文 @@ -12,12 +13,12 @@ public class RequestContext { private static final ThreadLocal REQUEST_ENTITY_THREAD_LOCAL = new InheritableThreadLocal<>(); - public static HttpServletRequest getHttpServletRequest() { + public static MagicHttpServletRequest getHttpServletRequest() { RequestEntity requestEntity = REQUEST_ENTITY_THREAD_LOCAL.get(); return requestEntity == null ? null : requestEntity.getRequest(); } - public static HttpServletResponse getHttpServletResponse() { + public static MagicHttpServletResponse getHttpServletResponse() { RequestEntity requestEntity = REQUEST_ENTITY_THREAD_LOCAL.get(); return requestEntity == null ? null : requestEntity.getResponse(); } diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/core/context/RequestEntity.java b/magic-api/src/main/java/org/ssssssss/magicapi/core/context/RequestEntity.java index 3991ccc0..764f8bdf 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/core/context/RequestEntity.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/core/context/RequestEntity.java @@ -2,10 +2,10 @@ package org.ssssssss.magicapi.core.context; import org.ssssssss.magicapi.core.model.ApiInfo; import org.ssssssss.magicapi.core.model.DebugRequest; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletResponse; import org.ssssssss.script.MagicScriptContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.util.Map; import java.util.UUID; @@ -19,8 +19,8 @@ public class RequestEntity { private final Long requestTime = System.currentTimeMillis(); private final String requestId = UUID.randomUUID().toString().replace("-", ""); private ApiInfo apiInfo; - private HttpServletRequest request; - private HttpServletResponse response; + private MagicHttpServletRequest request; + private MagicHttpServletResponse response; private boolean requestedFromTest; private Map parameters; private Map pathVariables; @@ -47,21 +47,21 @@ public class RequestEntity { return this; } - public HttpServletRequest getRequest() { + public MagicHttpServletRequest getRequest() { return request; } - public RequestEntity request(HttpServletRequest request) { + public RequestEntity request(MagicHttpServletRequest request) { this.request = request; this.debugRequest = DebugRequest.create(request); return this; } - public HttpServletResponse getResponse() { + public MagicHttpServletResponse getResponse() { return response; } - public RequestEntity response(HttpServletResponse response) { + public RequestEntity response(MagicHttpServletResponse response) { this.response = response; return this; } diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/core/context/SessionContext.java b/magic-api/src/main/java/org/ssssssss/magicapi/core/context/SessionContext.java index ad1cfdd3..e4372141 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/core/context/SessionContext.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/core/context/SessionContext.java @@ -1,6 +1,7 @@ package org.ssssssss.magicapi.core.context; -import javax.servlet.http.HttpSession; +import org.ssssssss.magicapi.core.servlet.MagicHttpSession; + import java.util.HashMap; /** @@ -10,9 +11,9 @@ import java.util.HashMap; */ public class SessionContext extends HashMap { - private final HttpSession session; + private final MagicHttpSession session; - public SessionContext(HttpSession session) { + public SessionContext(MagicHttpSession session) { this.session = session; } diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/core/interceptor/AuthorizationInterceptor.java b/magic-api/src/main/java/org/ssssssss/magicapi/core/interceptor/AuthorizationInterceptor.java index a79797c1..3c8866aa 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/core/interceptor/AuthorizationInterceptor.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/core/interceptor/AuthorizationInterceptor.java @@ -4,8 +4,7 @@ import org.ssssssss.magicapi.core.context.MagicUser; import org.ssssssss.magicapi.core.exception.MagicLoginException; import org.ssssssss.magicapi.core.model.Group; import org.ssssssss.magicapi.core.model.MagicEntity; - -import javax.servlet.http.HttpServletRequest; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest; /** * UI权限拦截器 @@ -64,7 +63,7 @@ public interface AuthorizationInterceptor { * @param authorization 鉴权方法 * @return true 有权限访问, false 无权限访问 */ - default boolean allowVisit(MagicUser magicUser, HttpServletRequest request, Authorization authorization) { + default boolean allowVisit(MagicUser magicUser, MagicHttpServletRequest request, Authorization authorization) { return true; } @@ -77,7 +76,7 @@ public interface AuthorizationInterceptor { * @param entity 接口、函数、数据源信息 * @return true 有权限访问, false 无权限访问 */ - default boolean allowVisit(MagicUser magicUser, HttpServletRequest request, Authorization authorization, MagicEntity entity) { + default boolean allowVisit(MagicUser magicUser, MagicHttpServletRequest request, Authorization authorization, MagicEntity entity) { return allowVisit(magicUser, request, authorization); } @@ -91,7 +90,7 @@ public interface AuthorizationInterceptor { * @param group 分组信息 * @return true 有权限访问, false 无权限访问 */ - default boolean allowVisit(MagicUser magicUser, HttpServletRequest request, Authorization authorization, Group group) { + default boolean allowVisit(MagicUser magicUser, MagicHttpServletRequest request, Authorization authorization, Group group) { return allowVisit(magicUser, request, authorization); } diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/core/interceptor/MagicWebRequestInterceptor.java b/magic-api/src/main/java/org/ssssssss/magicapi/core/interceptor/MagicWebRequestInterceptor.java index ef9c220e..b5907e03 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/core/interceptor/MagicWebRequestInterceptor.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/core/interceptor/MagicWebRequestInterceptor.java @@ -1,22 +1,16 @@ package org.ssssssss.magicapi.core.interceptor; import org.springframework.web.method.HandlerMethod; -import org.springframework.web.servlet.HandlerInterceptor; +import org.ssssssss.magicapi.core.annotation.Valid; import org.ssssssss.magicapi.core.config.Constants; import org.ssssssss.magicapi.core.config.MagicCorsFilter; -import org.ssssssss.magicapi.core.annotation.Valid; -import org.ssssssss.magicapi.core.web.MagicController; import org.ssssssss.magicapi.core.exception.MagicLoginException; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletResponse; +import org.ssssssss.magicapi.core.web.MagicController; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -/** - * /magic/web相关接口的拦截器 - * - * @author mxd - */ -public class MagicWebRequestInterceptor implements HandlerInterceptor { +public abstract class MagicWebRequestInterceptor { private final MagicCorsFilter magicCorsFilter; @@ -27,8 +21,7 @@ public class MagicWebRequestInterceptor implements HandlerInterceptor { this.authorizationInterceptor = authorizationInterceptor; } - @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws MagicLoginException { + public void handle(Object handler, MagicHttpServletRequest request, MagicHttpServletResponse response) throws MagicLoginException { HandlerMethod handlerMethod; if (handler instanceof HandlerMethod) { handlerMethod = (HandlerMethod) handler; @@ -46,6 +39,5 @@ public class MagicWebRequestInterceptor implements HandlerInterceptor { ((MagicController) handler).doValid(request, valid); } } - return true; } } diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/core/interceptor/RequestInterceptor.java b/magic-api/src/main/java/org/ssssssss/magicapi/core/interceptor/RequestInterceptor.java index e3fbe89e..d303aabb 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/core/interceptor/RequestInterceptor.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/core/interceptor/RequestInterceptor.java @@ -1,11 +1,11 @@ package org.ssssssss.magicapi.core.interceptor; -import org.ssssssss.magicapi.core.model.ApiInfo; import org.ssssssss.magicapi.core.context.RequestEntity; +import org.ssssssss.magicapi.core.model.ApiInfo; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletResponse; import org.ssssssss.script.MagicScriptContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; /** * 请求拦截器 @@ -34,7 +34,7 @@ public interface RequestInterceptor { * @return 当返回对象时,直接将此对象返回到页面,返回null时,继续执行后续操作 * @throws Exception 处理失败时抛出的异常 */ - default Object preHandle(ApiInfo info, MagicScriptContext context, HttpServletRequest request, HttpServletResponse response) throws Exception { + default Object preHandle(ApiInfo info, MagicScriptContext context, MagicHttpServletRequest request, MagicHttpServletResponse response) throws Exception { return null; } @@ -50,7 +50,7 @@ public interface RequestInterceptor { * @return 返回到页面的对象, 当返回null时执行后续拦截器,否则直接返回该值,不执行后续拦截器 * @throws Exception 处理失败时抛出的异常 */ - default Object postHandle(ApiInfo info, MagicScriptContext context, Object returnValue, HttpServletRequest request, HttpServletResponse response) throws Exception { + default Object postHandle(ApiInfo info, MagicScriptContext context, Object returnValue, MagicHttpServletRequest request, MagicHttpServletResponse response) throws Exception { return null; } @@ -86,7 +86,7 @@ public interface RequestInterceptor { * @param response HttpServletResponse * @param throwable 异常对象 */ - default void afterCompletion(ApiInfo info, MagicScriptContext context, Object returnValue, HttpServletRequest request, HttpServletResponse response, Throwable throwable) { + default void afterCompletion(ApiInfo info, MagicScriptContext context, Object returnValue, MagicHttpServletRequest request, MagicHttpServletResponse response, Throwable throwable) { } diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/core/model/DebugRequest.java b/magic-api/src/main/java/org/ssssssss/magicapi/core/model/DebugRequest.java index a9d8e583..dfddedd9 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/core/model/DebugRequest.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/core/model/DebugRequest.java @@ -1,29 +1,29 @@ package org.ssssssss.magicapi.core.model; import org.ssssssss.magicapi.core.config.WebSocketSessionManager; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest; import org.ssssssss.magicapi.utils.JsonUtils; import org.ssssssss.script.MagicScriptDebugContext; import org.ssssssss.script.functions.ObjectConvertExtension; -import javax.servlet.http.HttpServletRequest; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.stream.Collectors; -import static org.ssssssss.magicapi.core.config.MessageType.BREAKPOINT; import static org.ssssssss.magicapi.core.config.Constants.*; +import static org.ssssssss.magicapi.core.config.MessageType.BREAKPOINT; public class DebugRequest { - private HttpServletRequest request; + private final MagicHttpServletRequest request; - private DebugRequest(HttpServletRequest request) { + private DebugRequest(MagicHttpServletRequest request) { this.request = request; } - public static DebugRequest create(HttpServletRequest request){ + public static DebugRequest create(MagicHttpServletRequest request){ return new DebugRequest(request); } diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/core/service/impl/DefaultMagicAPIService.java b/magic-api/src/main/java/org/ssssssss/magicapi/core/service/impl/DefaultMagicAPIService.java index e76df5f8..3cad8c8a 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/core/service/impl/DefaultMagicAPIService.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/core/service/impl/DefaultMagicAPIService.java @@ -11,27 +11,24 @@ import org.springframework.http.MediaType; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; -import org.springframework.web.context.request.RequestAttributes; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; import org.ssssssss.magicapi.core.annotation.MagicModule; import org.ssssssss.magicapi.core.config.Constants; import org.ssssssss.magicapi.core.config.JsonCodeConstants; import org.ssssssss.magicapi.core.config.WebSocketSessionManager; import org.ssssssss.magicapi.core.context.RequestEntity; -import org.ssssssss.magicapi.core.handler.MagicWebSocketDispatcher; -import org.ssssssss.magicapi.core.model.*; import org.ssssssss.magicapi.core.event.EventAction; import org.ssssssss.magicapi.core.event.MagicEvent; import org.ssssssss.magicapi.core.exception.MagicAPIException; -import org.ssssssss.magicapi.core.exception.MagicResourceNotFoundException; -import org.ssssssss.magicapi.function.model.FunctionInfo; -import org.ssssssss.magicapi.core.service.MagicAPIService; +import org.ssssssss.magicapi.core.handler.MagicWebSocketDispatcher; import org.ssssssss.magicapi.core.interceptor.ResultProvider; -import org.ssssssss.magicapi.utils.ScriptManager; +import org.ssssssss.magicapi.core.model.*; +import org.ssssssss.magicapi.core.service.MagicAPIService; import org.ssssssss.magicapi.core.service.MagicResourceService; +import org.ssssssss.magicapi.core.servlet.MagicRequestContextHolder; +import org.ssssssss.magicapi.function.model.FunctionInfo; import org.ssssssss.magicapi.function.service.FunctionMagicDynamicRegistry; import org.ssssssss.magicapi.utils.PathUtils; +import org.ssssssss.magicapi.utils.ScriptManager; import org.ssssssss.magicapi.utils.SignUtils; import org.ssssssss.script.MagicScriptContext; @@ -53,6 +50,7 @@ public class DefaultMagicAPIService implements MagicAPIService, JsonCodeConstant private final RequestMagicDynamicRegistry requestMagicDynamicRegistry; private final FunctionMagicDynamicRegistry functionMagicDynamicRegistry; private final String prefix; + private final MagicRequestContextHolder magicRequestHolder; public DefaultMagicAPIService(ResultProvider resultProvider, String instanceId, @@ -61,6 +59,7 @@ public class DefaultMagicAPIService implements MagicAPIService, JsonCodeConstant FunctionMagicDynamicRegistry functionMagicDynamicRegistry, boolean throwException, String prefix, + MagicRequestContextHolder magicRequestHolder, ApplicationEventPublisher publisher) { this.resultProvider = resultProvider; this.requestMagicDynamicRegistry = requestMagicDynamicRegistry; @@ -69,6 +68,7 @@ public class DefaultMagicAPIService implements MagicAPIService, JsonCodeConstant this.resourceService = resourceService; this.instanceId = instanceId; this.prefix = StringUtils.defaultIfBlank(prefix, ""); + this.magicRequestHolder = magicRequestHolder; this.publisher = publisher; } @@ -110,11 +110,8 @@ public class DefaultMagicAPIService implements MagicAPIService, JsonCodeConstant public T call(String method, String path, Map context) { RequestEntity requestEntity = RequestEntity.create(); try { - RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); - if (requestAttributes instanceof ServletRequestAttributes) { - requestEntity.request(((ServletRequestAttributes) requestAttributes).getRequest()) - .response(((ServletRequestAttributes) requestAttributes).getResponse()); - } + + requestEntity.request(magicRequestHolder.getRequest()).response(magicRequestHolder.getResponse()); return (T) resultProvider.buildResult(requestEntity, (Object) execute(requestEntity, method, path, context)); } catch (Throwable root) { if (throwException) { diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/core/service/impl/RequestMagicDynamicRegistry.java b/magic-api/src/main/java/org/ssssssss/magicapi/core/service/impl/RequestMagicDynamicRegistry.java index 3e616baf..24b957e0 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/core/service/impl/RequestMagicDynamicRegistry.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/core/service/impl/RequestMagicDynamicRegistry.java @@ -7,7 +7,6 @@ import org.springframework.context.event.EventListener; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.servlet.HandlerMapping; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; -import org.ssssssss.magicapi.core.web.RequestHandler; import org.ssssssss.magicapi.core.config.MagicConfiguration; import org.ssssssss.magicapi.core.event.FileEvent; import org.ssssssss.magicapi.core.event.GroupEvent; @@ -15,6 +14,9 @@ import org.ssssssss.magicapi.core.exception.InvalidArgumentException; import org.ssssssss.magicapi.core.model.ApiInfo; import org.ssssssss.magicapi.core.service.AbstractMagicDynamicRegistry; import org.ssssssss.magicapi.core.service.MagicResourceStorage; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletResponse; +import org.ssssssss.magicapi.core.web.RequestHandler; import org.ssssssss.magicapi.utils.Mapping; import org.ssssssss.magicapi.utils.PathUtils; import org.ssssssss.magicapi.utils.ScriptManager; @@ -24,8 +26,6 @@ import org.ssssssss.script.exception.MagicExitException; import org.ssssssss.script.runtime.ExitValue; import org.ssssssss.script.runtime.function.MagicScriptLambdaFunction; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.lang.reflect.Method; import java.util.LinkedHashMap; import java.util.Map; @@ -39,7 +39,7 @@ public class RequestMagicDynamicRegistry extends AbstractMagicDynamicRegistry getHeaders(String name); + + String getRequestURI(); + + String getMethod(); + + void setAttribute(String key, Object value); + + String[] getParameterValues(String name); + + Object getAttribute(String name); + + HttpInputMessage getHttpInputMessage(); + + String getContentType(); + + MagicHttpSession getSession(); + + MagicCookie[] getCookies(); + + InputStream getInputStream() throws IOException; + + boolean isMultipart(); + + String getRemoteAddr(); + + MultipartRequest resolveMultipart(); + + Principal getUserPrincipal(); +} + + diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/core/servlet/MagicHttpServletResponse.java b/magic-api/src/main/java/org/ssssssss/magicapi/core/servlet/MagicHttpServletResponse.java new file mode 100644 index 00000000..44f03802 --- /dev/null +++ b/magic-api/src/main/java/org/ssssssss/magicapi/core/servlet/MagicHttpServletResponse.java @@ -0,0 +1,20 @@ +package org.ssssssss.magicapi.core.servlet; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Collection; + +public interface MagicHttpServletResponse { + + public void setHeader(String name, String value); + + public void addHeader(String name, String value); + + public void sendRedirect(String location) throws IOException; + + public void addCookie(MagicCookie cookie); + + public OutputStream getOutputStream() throws IOException; + + public Collection getHeaderNames(); +} diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/core/servlet/MagicHttpSession.java b/magic-api/src/main/java/org/ssssssss/magicapi/core/servlet/MagicHttpSession.java new file mode 100644 index 00000000..90dfce2b --- /dev/null +++ b/magic-api/src/main/java/org/ssssssss/magicapi/core/servlet/MagicHttpSession.java @@ -0,0 +1,8 @@ +package org.ssssssss.magicapi.core.servlet; + +public interface MagicHttpSession { + + Object getAttribute(String key); + + void setAttribute(String key, Object value); +} diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/core/servlet/MagicRequestContextHolder.java b/magic-api/src/main/java/org/ssssssss/magicapi/core/servlet/MagicRequestContextHolder.java new file mode 100644 index 00000000..4978477a --- /dev/null +++ b/magic-api/src/main/java/org/ssssssss/magicapi/core/servlet/MagicRequestContextHolder.java @@ -0,0 +1,23 @@ +package org.ssssssss.magicapi.core.servlet; + +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import java.util.function.Function; + +public interface MagicRequestContextHolder { + + default R convert(Function function){ + RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); + if (requestAttributes instanceof ServletRequestAttributes) { + ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) requestAttributes); + return function.apply(servletRequestAttributes); + } + return null; + } + + MagicHttpServletRequest getRequest(); + + MagicHttpServletResponse getResponse(); +} diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/core/web/MagicController.java b/magic-api/src/main/java/org/ssssssss/magicapi/core/web/MagicController.java index 10433e42..d494acf4 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/core/web/MagicController.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/core/web/MagicController.java @@ -2,20 +2,22 @@ package org.ssssssss.magicapi.core.web; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; +import org.ssssssss.magicapi.backup.service.MagicBackupService; +import org.ssssssss.magicapi.core.annotation.Valid; import org.ssssssss.magicapi.core.config.Constants; import org.ssssssss.magicapi.core.config.JsonCodeConstants; import org.ssssssss.magicapi.core.config.MagicConfiguration; -import org.ssssssss.magicapi.core.annotation.Valid; -import org.ssssssss.magicapi.core.model.*; +import org.ssssssss.magicapi.core.context.MagicUser; import org.ssssssss.magicapi.core.exception.InvalidArgumentException; import org.ssssssss.magicapi.core.exception.MagicLoginException; import org.ssssssss.magicapi.core.interceptor.Authorization; -import org.ssssssss.magicapi.core.context.MagicUser; +import org.ssssssss.magicapi.core.model.Group; +import org.ssssssss.magicapi.core.model.JsonBean; +import org.ssssssss.magicapi.core.model.MagicEntity; import org.ssssssss.magicapi.core.service.MagicAPIService; -import org.ssssssss.magicapi.backup.service.MagicBackupService; import org.ssssssss.magicapi.core.service.MagicResourceService; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest; -import javax.servlet.http.HttpServletRequest; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; @@ -37,7 +39,7 @@ public class MagicController implements JsonCodeConstants { this.magicBackupService = configuration.getMagicBackupService(); } - public void doValid(HttpServletRequest request, Valid valid) { + public void doValid(MagicHttpServletRequest request, Valid valid) { if (valid != null) { if (!valid.readonly() && configuration.getWorkspace().readonly()) { throw new InvalidArgumentException(IS_READ_ONLY); @@ -51,7 +53,7 @@ public class MagicController implements JsonCodeConstants { /** * 判断是否有权限访问按钮 */ - boolean allowVisit(HttpServletRequest request, Authorization authorization) { + boolean allowVisit(MagicHttpServletRequest request, Authorization authorization) { if (authorization == null) { return true; } @@ -59,7 +61,7 @@ public class MagicController implements JsonCodeConstants { return configuration.getAuthorizationInterceptor().allowVisit(magicUser, request, authorization); } - boolean allowVisit(HttpServletRequest request, Authorization authorization, MagicEntity entity) { + boolean allowVisit(MagicHttpServletRequest request, Authorization authorization, MagicEntity entity) { if (authorization == null) { return true; } @@ -67,7 +69,7 @@ public class MagicController implements JsonCodeConstants { return configuration.getAuthorizationInterceptor().allowVisit(magicUser, request, authorization, entity); } - boolean allowVisit(HttpServletRequest request, Authorization authorization, Group group) { + boolean allowVisit(MagicHttpServletRequest request, Authorization authorization, Group group) { if (authorization == null) { return true; } @@ -75,7 +77,7 @@ public class MagicController implements JsonCodeConstants { return configuration.getAuthorizationInterceptor().allowVisit(magicUser, request, authorization, group); } - List entities(HttpServletRequest request, Authorization authorization) { + List entities(MagicHttpServletRequest request, Authorization authorization) { MagicResourceService service = configuration.getMagicResourceService(); return service.tree() .values() diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/core/web/MagicResourceController.java b/magic-api/src/main/java/org/ssssssss/magicapi/core/web/MagicResourceController.java index df286cf9..ca8b92f8 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/core/web/MagicResourceController.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/core/web/MagicResourceController.java @@ -10,9 +10,9 @@ import org.ssssssss.magicapi.core.resource.FileResource; import org.ssssssss.magicapi.core.resource.Resource; import org.ssssssss.magicapi.core.service.MagicDynamicRegistry; import org.ssssssss.magicapi.core.service.MagicResourceService; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest; import org.ssssssss.magicapi.utils.IoUtils; -import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.HashMap; import java.util.List; @@ -31,7 +31,7 @@ public class MagicResourceController extends MagicController implements MagicExc @PostMapping("/resource/folder/save") @ResponseBody - public JsonBean saveFolder(@RequestBody Group group, HttpServletRequest request) { + public JsonBean saveFolder(@RequestBody Group group, MagicHttpServletRequest request) { isTrue(allowVisit(request, Authorization.SAVE, group), PERMISSION_INVALID); Resource resource = service.getResource(); if(resource instanceof FileResource){ @@ -45,7 +45,7 @@ public class MagicResourceController extends MagicController implements MagicExc @PostMapping("/resource/folder/copy") @ResponseBody - public JsonBean saveFolder(String src, String target, HttpServletRequest request) { + public JsonBean saveFolder(String src, String target, MagicHttpServletRequest request) { Group srcGroup = service.getGroup(src); notNull(srcGroup, GROUP_NOT_FOUND); isTrue(allowVisit(request, Authorization.VIEW, srcGroup), PERMISSION_INVALID); @@ -59,7 +59,7 @@ public class MagicResourceController extends MagicController implements MagicExc @PostMapping("/resource/delete") @ResponseBody - public JsonBean delete(String id, HttpServletRequest request) { + public JsonBean delete(String id, MagicHttpServletRequest request) { Group group = service.getGroup(id); if(group == null){ MagicEntity entity = service.file(id); @@ -73,7 +73,7 @@ public class MagicResourceController extends MagicController implements MagicExc @PostMapping("/resource/file/{folder}/save") @ResponseBody - public JsonBean saveFile(@PathVariable("folder") String folder, String auto, HttpServletRequest request) throws IOException { + public JsonBean saveFile(@PathVariable("folder") String folder, String auto, MagicHttpServletRequest request) throws IOException { byte[] bytes = IoUtils.bytes(request.getInputStream()); MagicEntity entity = configuration.getMagicDynamicRegistries().stream() .map(MagicDynamicRegistry::getMagicResourceStorage) @@ -97,7 +97,7 @@ public class MagicResourceController extends MagicController implements MagicExc @GetMapping("/resource/file/{id}") @ResponseBody - public JsonBean detail(@PathVariable("id") String id, HttpServletRequest request) { + public JsonBean detail(@PathVariable("id") String id, MagicHttpServletRequest request) { MagicEntity entity = MagicConfiguration.getMagicResourceService().file(id); isTrue(allowVisit(request, Authorization.VIEW, entity), PERMISSION_INVALID); return new JsonBean<>(MagicConfiguration.getMagicResourceService().file(id)); @@ -105,7 +105,7 @@ public class MagicResourceController extends MagicController implements MagicExc @PostMapping("/resource/move") @ResponseBody - public JsonBean move(String src, String groupId, HttpServletRequest request) { + public JsonBean move(String src, String groupId, MagicHttpServletRequest request) { Group group = service.getGroup(src); if(group == null){ MagicEntity entity = service.file(src); @@ -123,7 +123,7 @@ public class MagicResourceController extends MagicController implements MagicExc @PostMapping("/resource/lock") @ResponseBody - public JsonBean lock(String id, HttpServletRequest request) { + public JsonBean lock(String id, MagicHttpServletRequest request) { MagicEntity entity = service.file(id); notNull(entity, FILE_NOT_FOUND); isTrue(allowVisit(request, Authorization.LOCK, entity), PERMISSION_INVALID); @@ -132,7 +132,7 @@ public class MagicResourceController extends MagicController implements MagicExc @PostMapping("/resource/unlock") @ResponseBody - public JsonBean unlock(String id, HttpServletRequest request) { + public JsonBean unlock(String id, MagicHttpServletRequest request) { MagicEntity entity = service.file(id); notNull(entity, FILE_NOT_FOUND); isTrue(allowVisit(request, Authorization.UNLOCK, entity), PERMISSION_INVALID); @@ -141,7 +141,7 @@ public class MagicResourceController extends MagicController implements MagicExc @GetMapping("/resource") @ResponseBody - public JsonBean>>> resources(HttpServletRequest request) { + public JsonBean>>> resources(MagicHttpServletRequest request) { Map> tree = service.tree(); Map>> result = new HashMap<>(); tree.forEach((key, value) -> { @@ -164,7 +164,7 @@ public class MagicResourceController extends MagicController implements MagicExc return new JsonBean<>(result); } - private TreeNode> process(TreeNode groupNode, HttpServletRequest request) { + private TreeNode> process(TreeNode groupNode, MagicHttpServletRequest request) { TreeNode> value = new TreeNode<>(); value.setNode(groupNode.getNode()); groupNode.getChildren().stream() diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/core/web/MagicWorkbenchController.java b/magic-api/src/main/java/org/ssssssss/magicapi/core/web/MagicWorkbenchController.java index 741dc682..5f02c403 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/core/web/MagicWorkbenchController.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/core/web/MagicWorkbenchController.java @@ -10,17 +10,19 @@ import org.springframework.http.ResponseEntity; import org.springframework.util.ResourceUtils; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import org.ssssssss.magicapi.core.annotation.Valid; import org.ssssssss.magicapi.core.config.Constants; import org.ssssssss.magicapi.core.config.MagicAPIProperties; import org.ssssssss.magicapi.core.config.MagicConfiguration; -import org.ssssssss.magicapi.core.annotation.Valid; -import org.ssssssss.magicapi.core.model.*; +import org.ssssssss.magicapi.core.context.MagicUser; import org.ssssssss.magicapi.core.exception.MagicLoginException; import org.ssssssss.magicapi.core.interceptor.Authorization; -import org.ssssssss.magicapi.core.context.MagicUser; -import org.ssssssss.magicapi.modules.servlet.ResponseModule; -import org.ssssssss.magicapi.modules.db.SQLModule; +import org.ssssssss.magicapi.core.model.*; import org.ssssssss.magicapi.core.service.MagicAPIService; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletResponse; +import org.ssssssss.magicapi.modules.db.SQLModule; +import org.ssssssss.magicapi.modules.servlet.ResponseModule; import org.ssssssss.magicapi.utils.ClassScanner; import org.ssssssss.magicapi.utils.IoUtils; import org.ssssssss.magicapi.utils.SignUtils; @@ -31,8 +33,6 @@ import org.ssssssss.script.ScriptClass; import org.ssssssss.script.parsing.Span; import org.ssssssss.script.parsing.Tokenizer; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; @@ -74,7 +74,7 @@ public class MagicWorkbenchController extends MagicController implements MagicEx @GetMapping({"", "/"}) @Valid(requireLogin = false) - public String redirectIndex(HttpServletRequest request) { + public String redirectIndex(MagicHttpServletRequest request) { if (request.getRequestURI().endsWith("/")) { return "redirect:./index.html"; } @@ -139,7 +139,7 @@ public class MagicWorkbenchController extends MagicController implements MagicEx @PostMapping("/login") @ResponseBody @Valid(requireLogin = false) - public JsonBean login(String username, String password, HttpServletRequest request, HttpServletResponse response) throws MagicLoginException { + public JsonBean login(String username, String password, MagicHttpServletRequest request, MagicHttpServletResponse response) throws MagicLoginException { if (configuration.getAuthorizationInterceptor().requireLogin()) { if (StringUtils.isBlank(username) && StringUtils.isBlank(password)) { try { @@ -158,7 +158,7 @@ public class MagicWorkbenchController extends MagicController implements MagicEx @PostMapping("/user") @ResponseBody - public JsonBean user(HttpServletRequest request) { + public JsonBean user(MagicHttpServletRequest request) { if (configuration.getAuthorizationInterceptor().requireLogin()) { try { return new JsonBean<>(configuration.getAuthorizationInterceptor().getUserByToken(request.getHeader(Constants.MAGIC_TOKEN_HEADER))); @@ -172,7 +172,7 @@ public class MagicWorkbenchController extends MagicController implements MagicEx @PostMapping("/logout") @ResponseBody @Valid(requireLogin = false) - public JsonBean logout(HttpServletRequest request) { + public JsonBean logout(MagicHttpServletRequest request) { configuration.getAuthorizationInterceptor().logout(request.getHeader(Constants.MAGIC_TOKEN_HEADER)); return new JsonBean<>(); } @@ -194,7 +194,7 @@ public class MagicWorkbenchController extends MagicController implements MagicEx @GetMapping("/reload") @ResponseBody - public JsonBean reload(HttpServletRequest request) { + public JsonBean reload(MagicHttpServletRequest request) { isTrue(allowVisit(request, Authorization.RELOAD), PERMISSION_INVALID); MagicConfiguration.getMagicResourceService().refresh(); return new JsonBean<>(true); @@ -202,7 +202,7 @@ public class MagicWorkbenchController extends MagicController implements MagicEx @GetMapping("/search") @ResponseBody - public JsonBean>> search(String keyword, HttpServletRequest request) { + public JsonBean>> search(String keyword, MagicHttpServletRequest request) { if (StringUtils.isBlank(keyword)) { return new JsonBean<>(Collections.emptyList()); } @@ -228,7 +228,7 @@ public class MagicWorkbenchController extends MagicController implements MagicEx @GetMapping("/todo") @ResponseBody @Valid - public JsonBean>> todo(HttpServletRequest request) { + public JsonBean>> todo(MagicHttpServletRequest request) { List entities = entities(request, Authorization.VIEW); List> result = new ArrayList<>(entities.size()); for (MagicEntity entity : entities) { @@ -279,7 +279,7 @@ public class MagicWorkbenchController extends MagicController implements MagicEx @RequestMapping("/download") @Valid(authorization = Authorization.DOWNLOAD) @ResponseBody - public ResponseEntity download(String groupId, @RequestBody(required = false) List resources, HttpServletRequest request) throws IOException { + public ResponseEntity download(String groupId, @RequestBody(required = false) List resources, MagicHttpServletRequest request) throws IOException { isTrue(allowVisit(request, Authorization.DOWNLOAD), PERMISSION_INVALID); ByteArrayOutputStream os = new ByteArrayOutputStream(); magicAPIService.download(groupId, resources, os); @@ -293,7 +293,7 @@ public class MagicWorkbenchController extends MagicController implements MagicEx @RequestMapping("/upload") @Valid(readonly = false, authorization = Authorization.UPLOAD) @ResponseBody - public JsonBean upload(MultipartFile file, String mode, HttpServletRequest request) throws IOException { + public JsonBean upload(MultipartFile file, String mode, MagicHttpServletRequest request) throws IOException { notNull(file, FILE_IS_REQUIRED); isTrue(allowVisit(request, Authorization.UPLOAD), PERMISSION_INVALID); if (configuration.getMagicBackupService() != null) { @@ -307,7 +307,7 @@ public class MagicWorkbenchController extends MagicController implements MagicEx @Valid(authorization = Authorization.PUSH) public JsonBean push(@RequestHeader("magic-push-target") String target, @RequestHeader("magic-push-secret-key") String secretKey, @RequestHeader("magic-push-mode") String mode, @RequestBody List resources, - HttpServletRequest request) { + MagicHttpServletRequest request) { isTrue(allowVisit(request, Authorization.PUSH), PERMISSION_INVALID); return magicAPIService.push(target, secretKey, mode, resources); } diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/core/web/RequestHandler.java b/magic-api/src/main/java/org/ssssssss/magicapi/core/web/RequestHandler.java index df58ca3b..0eb1f9b7 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/core/web/RequestHandler.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/core/web/RequestHandler.java @@ -7,30 +7,31 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.HttpMessageNotReadableException; -import org.springframework.http.server.ServletServerHttpRequest; import org.springframework.util.CollectionUtils; import org.springframework.util.LinkedCaseInsensitiveMap; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; +import org.ssssssss.magicapi.core.annotation.Valid; import org.ssssssss.magicapi.core.config.Constants; import org.ssssssss.magicapi.core.config.MagicConfiguration; -import org.ssssssss.magicapi.core.annotation.Valid; import org.ssssssss.magicapi.core.config.WebSocketSessionManager; import org.ssssssss.magicapi.core.context.CookieContext; import org.ssssssss.magicapi.core.context.RequestContext; import org.ssssssss.magicapi.core.context.RequestEntity; import org.ssssssss.magicapi.core.context.SessionContext; -import org.ssssssss.magicapi.core.model.*; import org.ssssssss.magicapi.core.exception.ValidateException; import org.ssssssss.magicapi.core.interceptor.RequestInterceptor; -import org.ssssssss.magicapi.core.logging.MagicLoggerContext; -import org.ssssssss.magicapi.modules.servlet.ResponseModule; import org.ssssssss.magicapi.core.interceptor.ResultProvider; -import org.ssssssss.magicapi.utils.ScriptManager; +import org.ssssssss.magicapi.core.logging.MagicLoggerContext; +import org.ssssssss.magicapi.core.model.*; import org.ssssssss.magicapi.core.service.impl.RequestMagicDynamicRegistry; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletResponse; +import org.ssssssss.magicapi.modules.servlet.ResponseModule; import org.ssssssss.magicapi.utils.PatternUtils; +import org.ssssssss.magicapi.utils.ScriptManager; import org.ssssssss.script.MagicScriptContext; import org.ssssssss.script.MagicScriptDebugContext; import org.ssssssss.script.exception.MagicScriptAssertException; @@ -40,8 +41,6 @@ import org.ssssssss.script.parsing.Span; import org.ssssssss.script.parsing.ast.literal.BooleanLiteral; import org.ssssssss.script.reflection.JavaInvoker; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.lang.reflect.Method; import java.math.BigDecimal; @@ -49,8 +48,8 @@ import java.util.*; import java.util.stream.Collectors; import static org.springframework.http.HttpHeaders.*; -import static org.ssssssss.magicapi.core.config.MessageType.EXCEPTION; import static org.ssssssss.magicapi.core.config.Constants.*; +import static org.ssssssss.magicapi.core.config.MessageType.EXCEPTION; /** * 请求入口处理 @@ -86,7 +85,7 @@ public class RequestHandler extends MagicController { */ @ResponseBody @Valid(requireLogin = false) - public Object invoke(HttpServletRequest request, HttpServletResponse response, + public Object invoke(MagicHttpServletRequest request, MagicHttpServletResponse response, @PathVariable(required = false) Map pathVariables, @RequestHeader(required = false) Map defaultHeaders, @RequestParam(required = false) Map parameters) throws Throwable { @@ -379,14 +378,14 @@ public class RequestHandler extends MagicController { /** * 读取RequestBody */ - private Object readRequestBody(HttpServletRequest request) throws IOException { + private Object readRequestBody(MagicHttpServletRequest request) throws IOException { if (configuration.getHttpMessageConverters() != null && request.getContentType() != null) { MediaType mediaType = MediaType.valueOf(request.getContentType()); Class clazz = Object.class; try { for (HttpMessageConverter converter : configuration.getHttpMessageConverters()) { if (converter.canRead(clazz, mediaType)) { - return converter.read(clazz, new ServletServerHttpRequest(request)); + return converter.read(clazz, request.getHttpInputMessage()); } } } catch (HttpMessageNotReadableException ignored) { @@ -457,7 +456,7 @@ public class RequestHandler extends MagicController { exposeHeaders.addAll(((ResponseEntity) returnValue).getHeaders().keySet()); } if (requestEntity.isRequestedFromTest()) { - HttpServletResponse response = requestEntity.getResponse(); + MagicHttpServletResponse response = requestEntity.getResponse(); exposeHeaders.addAll(response.getHeaderNames()); exposeHeaders.addAll(DEFAULT_ALLOW_READ_RESPONSE_HEADERS); } diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/modules/servlet/RequestModule.java b/magic-api/src/main/java/org/ssssssss/magicapi/modules/servlet/RequestModule.java index a41e4cfc..b32b0e90 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/modules/servlet/RequestModule.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/modules/servlet/RequestModule.java @@ -2,15 +2,17 @@ package org.ssssssss.magicapi.modules.servlet; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartRequest; -import org.springframework.web.multipart.MultipartResolver; import org.ssssssss.magicapi.core.annotation.MagicModule; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest; +import org.ssssssss.magicapi.core.servlet.MagicRequestContextHolder; import org.ssssssss.magicapi.utils.IpUtils; import org.ssssssss.script.annotation.Comment; -import javax.servlet.http.HttpServletRequest; -import java.util.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; import java.util.stream.Collectors; -import java.util.stream.Stream; /** * request 模块 @@ -20,12 +22,11 @@ import java.util.stream.Stream; @MagicModule("request") public class RequestModule { - private static MultipartResolver resolver; + private static MagicRequestContextHolder magicRequestContextHolder; - private static final String[] DEFAULT_IP_HEADER = new String[]{"X-Forwarded-For", "X-Real-IP", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR"}; - public RequestModule(MultipartResolver resolver) { - RequestModule.resolver = resolver; + public RequestModule(MagicRequestContextHolder magicRequestContextHolder) { + RequestModule.magicRequestContextHolder = magicRequestContextHolder; } /** @@ -61,14 +62,14 @@ public class RequestModule { * 获取原生HttpServletRequest对象 */ @Comment("获取原生HttpServletRequest对象") - public static HttpServletRequest get() { - return org.ssssssss.magicapi.utils.WebUtils.getRequest().orElse(null); + public static MagicHttpServletRequest get() { + return magicRequestContextHolder.getRequest(); } private static MultipartRequest getMultipartHttpServletRequest() { - HttpServletRequest request = get(); - if (request != null && resolver.isMultipart(request)) { - return resolver.resolveMultipart(request); + MagicHttpServletRequest request = get(); + if (request != null && request.isMultipart()) { + return request.resolveMultipart(); } return null; } @@ -80,7 +81,7 @@ public class RequestModule { */ @Comment("根据请求参数名获取值") public List getValues(@Comment(name = "name", value = "参数名") String name) { - HttpServletRequest request = get(); + MagicHttpServletRequest request = get(); if (request != null) { String[] values = request.getParameterValues(name); return values == null ? null : Arrays.asList(values); @@ -95,7 +96,7 @@ public class RequestModule { */ @Comment("根据header名获取值") public List getHeaders(@Comment(name = "name", value = "header名") String name) { - HttpServletRequest request = get(); + MagicHttpServletRequest request = get(); if (request != null) { Enumeration headers = request.getHeaders(name); return headers == null ? null : Collections.list(headers); @@ -105,7 +106,7 @@ public class RequestModule { @Comment("获取客户端IP") public String getClientIP(String... otherHeaderNames) { - HttpServletRequest request = get(); + MagicHttpServletRequest request = get(); if (request == null) { return null; } diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/modules/servlet/ResponseModule.java b/magic-api/src/main/java/org/ssssssss/magicapi/modules/servlet/ResponseModule.java index 3bced337..3048d33b 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/modules/servlet/ResponseModule.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/modules/servlet/ResponseModule.java @@ -4,17 +4,12 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.web.context.request.RequestAttributes; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; import org.ssssssss.magicapi.core.annotation.MagicModule; import org.ssssssss.magicapi.core.context.RequestContext; import org.ssssssss.magicapi.core.interceptor.ResultProvider; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletResponse; import org.ssssssss.script.annotation.Comment; -import org.ssssssss.script.functions.ObjectConvertExtension; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; @@ -79,7 +74,7 @@ public class ResponseModule { public ResponseModule addHeader(@Comment(name = "key", value = "header名") String key, @Comment(name = "value", value = "header值") String value) { if (StringUtils.isNotBlank(key)) { - HttpServletResponse response = getResponse(); + MagicHttpServletResponse response = getResponse(); if (response != null) { response.addHeader(key, value); } @@ -94,7 +89,7 @@ public class ResponseModule { public ResponseModule setHeader(@Comment(name = "key", value = "header名") String key, @Comment(name = "value", value = "header值") String value) { if (StringUtils.isNotBlank(key)) { - HttpServletResponse response = getResponse(); + MagicHttpServletResponse response = getResponse(); if (response != null) { response.setHeader(key, value); } @@ -102,41 +97,6 @@ public class ResponseModule { return this; } - /** - * 添加cookie - */ - @Comment("添加Cookie") - public ResponseModule addCookie(@Comment(name = "name", value = "cookie名") String name, - @Comment(name = "value", value = "cookie值") String value) { - if (StringUtils.isNotBlank(name)) { - addCookie(new Cookie(name, value)); - } - return this; - } - - /** - * 批量添加cookie - */ - @Comment("批量添加Cookie") - public ResponseModule addCookies(@Comment(name = "cookies", value = "Cookies") Map cookies, - @Comment(name = "options", value = "Cookie选项,如`path`、`httpOnly`、`domain`、`maxAge`") Map options) { - if (cookies != null) { - for (Map.Entry entry : cookies.entrySet()) { - addCookie(entry.getKey(), entry.getValue(), options); - } - } - return this; - } - - /** - * 批量添加cookie - */ - @Comment("批量添加Cookie") - public ResponseModule addCookies(@Comment(name = "cookies", value = "Cookies") Map cookies) { - return addCookies(cookies, null); - - } - /** * 获取OutputStream * @@ -144,67 +104,17 @@ public class ResponseModule { */ @Comment("获取OutputStream") public OutputStream getOutputStream() throws IOException { - HttpServletResponse response = getResponse(); + MagicHttpServletResponse response = getResponse(); return response.getOutputStream(); } - /** - * 添加cookie - */ - @Comment("添加Cookie") - public ResponseModule addCookie(@Comment(name = "name", value = "Cookie名") String name, - @Comment(name = "value", value = "Cookie值") String value, - @Comment(name = "options", value = "Cookie选项,如`path`、`httpOnly`、`domain`、`maxAge`") Map options) { - if (StringUtils.isNotBlank(name)) { - Cookie cookie = new Cookie(name, value); - if (options != null) { - Object path = options.get("path"); - if (path != null) { - cookie.setPath(path.toString()); - } - Object httpOnly = options.get("httpOnly"); - if (httpOnly != null) { - cookie.setHttpOnly("true".equalsIgnoreCase(httpOnly.toString())); - } - Object domain = options.get("domain"); - if (domain != null) { - cookie.setDomain(domain.toString()); - } - Object maxAge = options.get("maxAge"); - int age; - if (maxAge != null && (age = ObjectConvertExtension.asInt(maxAge, Integer.MIN_VALUE)) != Integer.MIN_VALUE) { - cookie.setMaxAge(age); - } - } - addCookie(cookie); - } - return this; - } @Comment("终止输出,执行此方法后不会对结果进行任何输出及处理") public NullValue end() { return NullValue.INSTANCE; } - /** - * 添加cookie - */ - @Comment("添加Cookie") - public ResponseModule addCookie(@Comment(name = "cookie", value = "Cookie对象") Cookie cookie) { - if (cookie != null) { - HttpServletResponse response = getResponse(); - if (response != null) { - response.addCookie(cookie); - } - } - return this; - } - - private HttpServletResponse getResponse() { - RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); - if (requestAttributes instanceof ServletRequestAttributes) { - return ((ServletRequestAttributes) requestAttributes).getResponse(); - } + private MagicHttpServletResponse getResponse() { return RequestContext.getHttpServletResponse(); } diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/utils/WebUtils.java b/magic-api/src/main/java/org/ssssssss/magicapi/utils/WebUtils.java index 569ca43c..d603ea1a 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/utils/WebUtils.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/utils/WebUtils.java @@ -1,13 +1,10 @@ package org.ssssssss.magicapi.utils; -import org.springframework.web.context.request.RequestAttributes; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; -import org.ssssssss.magicapi.core.context.RequestContext; import org.ssssssss.magicapi.core.config.Constants; import org.ssssssss.magicapi.core.context.MagicUser; +import org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest; +import org.ssssssss.magicapi.core.servlet.MagicRequestContextHolder; -import javax.servlet.http.HttpServletRequest; import java.security.Principal; import java.util.Optional; @@ -18,19 +15,13 @@ import java.util.Optional; */ public class WebUtils { - public static Optional getRequest() { - RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); - if (requestAttributes instanceof ServletRequestAttributes) { - return Optional.of(((ServletRequestAttributes) requestAttributes).getRequest()); - } - return Optional.ofNullable(RequestContext.getHttpServletRequest()); - } + public static MagicRequestContextHolder magicRequestContextHolder; public static String currentUserName() { - Optional request = getRequest(); + Optional request = Optional.ofNullable(magicRequestContextHolder.getRequest()); return request.map(r -> (MagicUser) r.getAttribute(Constants.ATTRIBUTE_MAGIC_USER)) .map(MagicUser::getUsername) - .orElseGet(() -> request.map(HttpServletRequest::getUserPrincipal) + .orElseGet(() -> request.map(MagicHttpServletRequest::getUserPrincipal) .map(Principal::getName) .orElse(null) ); diff --git a/pom.xml b/pom.xml index af83b394..65244fcc 100644 --- a/pom.xml +++ b/pom.xml @@ -45,8 +45,9 @@ magic-api magic-editor - magic-api-spring-boot-starter - magic-api-plugins + magic-api-servlet + magic-api-plugins + magic-api-spring-boot-starter @@ -62,6 +63,21 @@ magic-api ${project.version} + + org.ssssssss + magic-api-servlet + ${project.version} + + + org.ssssssss + magic-api-servlet-javaee + ${project.version} + + + org.ssssssss + magic-api-servlet-jakarta + ${project.version} + org.ssssssss magic-script