Commit 02897568 authored by liang.tang's avatar liang.tang
Browse files

magic-api

parents
Pipeline #222 failed with stages
in 0 seconds
import vue from '@vitejs/plugin-vue'
import viteSvgIcons from 'vite-plugin-svg-icons'
import path from 'path'
import pkg from './package.json'
export default {
base: './',
build: {
minify: false,
cssCodeSplit: true, // 将组件的 style 打包到 js 文件中
outDir: 'dist',
lib: {
target: 'esnext',
formats: ['iife'],
entry: path.resolve(__dirname, 'src/index.js'),
name: 'MagicTask',
fileName: (format) => `magic-task.${pkg.version}.${format}.js`
},
rollupOptions: {
// 确保外部化处理那些你不想打包进库的依赖
external: ['vue'],
output: {
// 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
globals: {
vue: 'Vue'
}
}
}
},
plugins: [
vue(),
viteSvgIcons({
iconDirs: [path.resolve(process.cwd(), 'src/icons')],
symbolId: 'magic-task-[name]'
}),
]
}
\ No newline at end of file
package org.ssssssss.magicapi.task.model;
import org.ssssssss.magicapi.core.model.MagicEntity;
import org.ssssssss.magicapi.core.model.PathMagicEntity;
import java.util.Objects;
public class TaskInfo extends PathMagicEntity {
/**
* cron 表达式
*/
private String cron;
/**
* 是否启用
*/
private boolean enabled;
/**
* 定时任务描述
*/
private String description;
public String getCron() {
return cron;
}
public void setCron(String cron) {
this.cron = cron;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public TaskInfo copy() {
TaskInfo info = new TaskInfo();
super.copyTo(info);
info.setCron(this.cron);
info.setEnabled(this.enabled);
info.setDescription(this.description);
return info;
}
@Override
public MagicEntity simple() {
TaskInfo info = new TaskInfo();
super.simple(info);
return info;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
TaskInfo taskInfo = (TaskInfo) o;
return Objects.equals(id, taskInfo.id) &&
Objects.equals(path, taskInfo.path) &&
Objects.equals(script, taskInfo.script) &&
Objects.equals(name, taskInfo.name) &&
Objects.equals(cron, taskInfo.cron) &&
Objects.equals(description, taskInfo.description) &&
Objects.equals(enabled, taskInfo.enabled);
}
@Override
public int hashCode() {
return Objects.hash(id, path, script, name, groupId, cron, enabled, description);
}
}
package org.ssssssss.magicapi.task.service;
import org.ssssssss.magicapi.core.service.AbstractPathMagicResourceStorage;
import org.ssssssss.magicapi.task.model.TaskInfo;
public class TaskInfoMagicResourceStorage extends AbstractPathMagicResourceStorage<TaskInfo> {
@Override
public String folder() {
return "task";
}
@Override
public Class<TaskInfo> magicClass() {
return TaskInfo.class;
}
@Override
public void validate(TaskInfo entity) {
notBlank(entity.getCron(), CRON_ID_REQUIRED);
}
@Override
public String buildMappingKey(TaskInfo info) {
return buildMappingKey(info, magicResourceService.getGroupPath(info.getGroupId()));
}
}
package org.ssssssss.magicapi.task.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.config.CronTask;
import org.springframework.scheduling.support.CronTrigger;
import org.ssssssss.magicapi.core.config.MagicConfiguration;
import org.ssssssss.magicapi.core.event.FileEvent;
import org.ssssssss.magicapi.core.event.GroupEvent;
import org.ssssssss.magicapi.core.service.AbstractMagicDynamicRegistry;
import org.ssssssss.magicapi.core.service.MagicResourceStorage;
import org.ssssssss.magicapi.task.model.TaskInfo;
import org.ssssssss.magicapi.utils.ScriptManager;
import org.ssssssss.script.MagicScriptContext;
import java.util.concurrent.ScheduledFuture;
public class TaskMagicDynamicRegistry extends AbstractMagicDynamicRegistry<TaskInfo> {
private final TaskScheduler taskScheduler;
private static final Logger logger = LoggerFactory.getLogger(TaskMagicDynamicRegistry.class);
private final boolean showLog;
public TaskMagicDynamicRegistry(MagicResourceStorage<TaskInfo> magicResourceStorage, TaskScheduler taskScheduler, boolean showLog) {
super(magicResourceStorage);
this.taskScheduler = taskScheduler;
this.showLog = showLog;
}
@EventListener(condition = "#event.type == 'task'")
public void onFileEvent(FileEvent event) {
processEvent(event);
}
@EventListener(condition = "#event.type == 'task'")
public void onGroupEvent(GroupEvent event) {
processEvent(event);
}
@Override
public boolean register(TaskInfo entity) {
unregister(entity);
return super.register(entity);
}
@Override
protected boolean register(MappingNode<TaskInfo> mappingNode) {
TaskInfo entity = mappingNode.getEntity();
if (taskScheduler != null) {
String scriptName = MagicConfiguration.getMagicResourceService().getScriptName(entity);
try {
CronTrigger trigger = new CronTrigger(entity.getCron());
CronTask cronTask = new CronTask(() -> {
if (entity.isEnabled()) {
try {
if (showLog) {
logger.info("定时任务:[{}]开始执行", scriptName);
}
MagicScriptContext magicScriptContext = new MagicScriptContext();
magicScriptContext.setScriptName(scriptName);
ScriptManager.executeScript(entity.getScript(), magicScriptContext);
} catch (Exception e) {
logger.error("定时任务执行出错", e);
} finally {
if (showLog) {
logger.info("定时任务:[{}]执行完毕", scriptName);
}
}
}
}, trigger);
mappingNode.setMappingData(taskScheduler.schedule(cronTask.getRunnable(), cronTask.getTrigger()));
} catch (Exception e) {
logger.error("定时任务:[{}]注册失败", scriptName, e);
}
logger.debug("注册定时任务:[{},{}]", MagicConfiguration.getMagicResourceService().getScriptName(entity), entity.getCron());
}
return true;
}
@Override
protected void unregister(MappingNode<TaskInfo> mappingNode) {
if (taskScheduler == null) {
return;
}
TaskInfo info = mappingNode.getEntity();
logger.debug("取消注册定时任务:[{}, {}, {}]", info.getName(), info.getPath(), info.getCron());
ScheduledFuture<?> scheduledFuture = (ScheduledFuture<?>) mappingNode.getMappingData();
if (scheduledFuture != null) {
try {
scheduledFuture.cancel(true);
} catch (Exception e) {
String scriptName = MagicConfiguration.getMagicResourceService().getScriptName(info);
logger.warn("定时任务:[{}]取消失败", scriptName, e);
}
}
}
}
package org.ssssssss.magicapi.task.starter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.ssssssss.magicapi.core.config.MagicPluginConfiguration;
import org.ssssssss.magicapi.core.model.Plugin;
import org.ssssssss.magicapi.core.web.MagicControllerRegister;
import org.ssssssss.magicapi.task.service.TaskInfoMagicResourceStorage;
import org.ssssssss.magicapi.task.service.TaskMagicDynamicRegistry;
import org.ssssssss.magicapi.task.web.MagicTaskController;
@Configuration
@EnableConfigurationProperties(MagicTaskConfig.class)
public class MagicAPITaskConfiguration implements MagicPluginConfiguration {
private final MagicTaskConfig config;
public MagicAPITaskConfiguration(MagicTaskConfig config) {
this.config = config;
}
@Bean
@ConditionalOnMissingBean
public TaskInfoMagicResourceStorage taskInfoMagicResourceStorage() {
return new TaskInfoMagicResourceStorage();
}
@Bean
@ConditionalOnMissingBean
public TaskMagicDynamicRegistry taskMagicDynamicRegistry(TaskInfoMagicResourceStorage taskInfoMagicResourceStorage) {
MagicTaskConfig.Shutdown shutdown = config.getShutdown();
ThreadPoolTaskScheduler poolTaskScheduler = null;
if(config.isEnable()){
poolTaskScheduler = new ThreadPoolTaskScheduler();
poolTaskScheduler.setPoolSize(config.getPool().getSize());
poolTaskScheduler.setWaitForTasksToCompleteOnShutdown(shutdown.isAwaitTermination());
if(shutdown.getAwaitTerminationPeriod() != null){
poolTaskScheduler.setAwaitTerminationSeconds((int) shutdown.getAwaitTerminationPeriod().getSeconds());
}
poolTaskScheduler.setThreadNamePrefix(config.getThreadNamePrefix());
poolTaskScheduler.initialize();
}
return new TaskMagicDynamicRegistry(taskInfoMagicResourceStorage, poolTaskScheduler, config.isLog());
}
@Override
public Plugin plugin() {
return new Plugin("定时任务", "MagicTask", "magic-task.1.0.0.iife.js");
}
@Override
public MagicControllerRegister controllerRegister() {
return (mapping, configuration) -> mapping.registerController(new MagicTaskController(configuration));
}
}
package org.ssssssss.magicapi.task.starter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.time.Duration;
@ConfigurationProperties("magic-api.task")
public class MagicTaskConfig {
/**
* 是否启用定时任务
*/
private boolean enable = true;
/**
* 是否打印日志
* @since 2.1.0
*/
private boolean log = false;
/**
* 线程池相关配置
*/
private final Pool pool = new Pool();
/**
* 关闭时相关配置
*/
private final Shutdown shutdown = new Shutdown();
/**
* 线程池前缀
*/
private String threadNamePrefix = "magic-task-";
public boolean isLog() {
return log;
}
public void setLog(boolean log) {
this.log = log;
}
public Pool getPool() {
return this.pool;
}
public Shutdown getShutdown() {
return this.shutdown;
}
public String getThreadNamePrefix() {
return this.threadNamePrefix;
}
public void setThreadNamePrefix(String threadNamePrefix) {
this.threadNamePrefix = threadNamePrefix;
}
public boolean isEnable() {
return enable;
}
public void setEnable(boolean enable) {
this.enable = enable;
}
public static class Pool {
/**
* 线程池大小
*/
private int size = Runtime.getRuntime().availableProcessors();
public int getSize() {
return this.size;
}
public void setSize(int size) {
this.size = size;
}
}
public static class Shutdown {
/**
* 关闭时是否等待任务执行完毕,默认为false
*/
private boolean awaitTermination;
/**
* 关闭时最多等待任务执行完毕的时间
*/
private Duration awaitTerminationPeriod;
public boolean isAwaitTermination() {
return this.awaitTermination;
}
public void setAwaitTermination(boolean awaitTermination) {
this.awaitTermination = awaitTermination;
}
public Duration getAwaitTerminationPeriod() {
return this.awaitTerminationPeriod;
}
public void setAwaitTerminationPeriod(Duration awaitTerminationPeriod) {
this.awaitTerminationPeriod = awaitTerminationPeriod;
}
}
}
package org.ssssssss.magicapi.task.web;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.ssssssss.magicapi.core.config.MagicConfiguration;
import org.ssssssss.magicapi.core.config.WebSocketSessionManager;
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;
public class MagicTaskController extends MagicController implements MagicExceptionHandler {
public MagicTaskController(MagicConfiguration configuration) {
super(configuration);
}
@PostMapping("/task/execute")
@ResponseBody
public JsonBean<Object> execute(String id, MagicHttpServletRequest request){
MagicEntity entity = MagicConfiguration.getMagicResourceService().file(id);
notNull(entity, FILE_NOT_FOUND);
String script = entity.getScript();
DebugRequest debugRequest = DebugRequest.create(request);
MagicLoggerContext.SESSION.set(debugRequest.getRequestedClientId());
String sessionAndScriptId = debugRequest.getRequestedClientId() + debugRequest.getRequestedScriptId();
try {
MagicScriptDebugContext magicScriptContext = debugRequest.createMagicScriptContext(configuration.getDebugTimeout());
WebSocketSessionManager.addMagicScriptContext(sessionAndScriptId, magicScriptContext);
magicScriptContext.setScriptName(MagicConfiguration.getMagicResourceService().getScriptName(entity));
return new JsonBean<>(ScriptManager.executeScript(script, magicScriptContext));
} finally {
WebSocketSessionManager.removeMagicScriptContext(sessionAndScriptId);
MagicLoggerContext.SESSION.remove();
}
}
}
org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.ssssssss.magicapi.task.starter.MagicAPITaskConfiguration
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-parent</artifactId>
<version>2.1.1</version>
</parent>
<artifactId>magic-api-plugins</artifactId>
<version>2.1.1</version>
<packaging>pom</packaging>
<name>magic-api-plugins</name>
<description>auto generate http api</description>
<modules>
<module>magic-api-plugin-task</module>
<module>magic-api-plugin-component</module>
<module>magic-api-plugin-swagger</module>
<module>magic-api-plugin-springdoc</module>
<module>magic-api-plugin-redis</module>
<module>magic-api-plugin-mongo</module>
<module>magic-api-plugin-elasticsearch</module>
<module>magic-api-plugin-cluster</module>
<module>magic-api-plugin-git</module>
</modules>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.ssssssss</groupId>
<artifactId>magic-script</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-servlet</artifactId>
<version>2.1.1</version>
</parent>
<artifactId>magic-api-servlet-jakarta</artifactId>
<packaging>jar</packaging>
<name>magic-api-servlet-jakarta</name>
<description>auto generate http api</description>
<properties>
<spring-boot.version>3.0.4</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>17</source>
<target>17</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
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();
}
@Override
public <T> T getCookie() {
return (T) cookie;
}
}
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);
}
}
package org.ssssssss.magicapi.servlet.jakarta;
import jakarta.servlet.http.Cookie;
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<String> 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() {
Cookie[] cookies = request.getCookies();
if(cookies == null){
return new MagicCookie[0];
}
return Arrays.stream(cookies).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();
}
@Override
public <T> T getRequest() {
return (T) request;
}
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);
}
}
}
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) {
response.addCookie(cookie.getCookie());
}
@Override
public void setContentType(String contentType) {
response.setContentType(contentType);
}
@Override
public void setCharacterEncoding(String characterEncoding) {
response.setCharacterEncoding(characterEncoding);
}
@Override
public OutputStream getOutputStream() throws IOException {
return response.getOutputStream();
}
@Override
public Collection<String> getHeaderNames() {
return response.getHeaderNames();
}
@Override
public <T> T getResponse() {
return (T) response;
}
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));
}
}
}
package org.ssssssss.magicapi.servlet.jakarta;
import jakarta.servlet.http.HttpSession;
import org.ssssssss.magicapi.core.servlet.MagicHttpSession;
public class MagicJakartaHttpSession implements MagicHttpSession {
private final 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);
}
@Override
public <T> T getSession() {
return (T) session;
}
}
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()));
}
}
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<String, String> 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<String, Object> 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<String, String> cookies,
@Comment(name = "options", value = "Cookie选项,如`path`、`httpOnly`、`domain`、`maxAge`") Map<String, Object> options) {
if (cookies != null) {
for (Map.Entry<String, String> entry : cookies.entrySet()) {
addCookie(module, entry.getKey(), entry.getValue(), options);
}
}
return module;
}
@Override
public Class<?> support() {
return ResponseModule.class;
}
}
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<MagicJakartaWebRequestInterceptor> magicWebRequestInterceptorProvider;
public MagicJakartaServletConfiguration(MagicAPIProperties properties, ObjectProvider<MagicJakartaWebRequestInterceptor> 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<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(0,new MagicJakartaHttpServletRequest.ArgumentsResolver());
resolvers.add(0,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<MagicJakartaCorsFilter> magicCorsFilterRegistrationBean() {
FilterRegistrationBean<MagicJakartaCorsFilter> registration = new FilterRegistrationBean<>(magicCorsFilter);
registration.addUrlPatterns("/*");
registration.setName("Magic Cors Filter");
registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
return registration;
}
}
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;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment