diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/ServerEngineFactory.java b/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/ServerEngineFactory.java
new file mode 100644
index 000000000..7bef41abf
--- /dev/null
+++ b/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/ServerEngineFactory.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2013-2024 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.dromara.hutool.http.server.engine;
+
+import org.dromara.hutool.core.lang.Singleton;
+import org.dromara.hutool.core.spi.ServiceLoader;
+import org.dromara.hutool.core.spi.SpiUtil;
+import org.dromara.hutool.core.text.StrUtil;
+import org.dromara.hutool.http.HttpException;
+import org.dromara.hutool.http.server.ServerConfig;
+import org.dromara.hutool.log.LogUtil;
+
+/**
+ * Http服务器引擎工厂类
+ *
+ * @author Looly
+ * @since 6.0.0
+ */
+public class ServerEngineFactory {
+
+ /**
+ * 获得单例的ServerEngine
+ *
+ * @return 单例的ServerEngine
+ */
+ public static ServerEngine getEngine() {
+ return Singleton.get(ServerEngine.class.getName(), ServerEngineFactory::createEngine);
+ }
+
+ /**
+ * 根据用户引入的HTTP客户端引擎jar,自动创建对应的HTTP服务器引擎对象
+ * 推荐创建的引擎单例使用,此方法每次调用会返回新的引擎
+ * 对不同引擎个性化配置,使用对应的{@link ServerConfig} 子类:
+ *
+ *
+ * 如果混用这些配置,则个性配置不生效
+ *
+ * @param config Http客户端配置
+ * @return {@code ClientEngine}
+ */
+ @SuppressWarnings("resource")
+ public static ServerEngine createEngine(final ServerConfig config) {
+ return createEngine().init(config);
+ }
+
+ /**
+ * 创建自定义引擎
+ *
+ * @param engineName 引擎名称,忽略大小写,如`Undertow`、`Tomcat`、`Jetty`、`SunHttpServer`
+ * @return 引擎
+ * @throws HttpException 无对应名称的引擎
+ */
+ public static ServerEngine createEngine(String engineName) throws HttpException {
+ if (!StrUtil.endWithIgnoreCase(engineName, "Engine")) {
+ engineName = engineName + "Engine";
+ }
+ final ServiceLoader list = SpiUtil.loadList(ServerEngine.class);
+ for (final String serviceName : list.getServiceNames()) {
+ if (StrUtil.endWithIgnoreCase(serviceName, engineName)) {
+ return list.getService(serviceName);
+ }
+ }
+ throw new HttpException("No such engine named: " + engineName);
+ }
+
+ /**
+ * 根据用户引入的HTTP服务器引擎jar,自动创建对应的HTTP客服务器引擎对象
+ * 推荐创建的引擎单例使用,此方法每次调用会返回新的引擎
+ *
+ * @return {@code ServerEngine}
+ */
+ public static ServerEngine createEngine() {
+ // SunServerEngine托底,始终不空
+ final ServerEngine engine = SpiUtil.loadFirstAvailable(ServerEngine.class);
+ LogUtil.debug("Use [{}] Http Engine As Default.", StrUtil.removeSuffix(engine.getClass().getSimpleName(), "Engine"));
+ return engine;
+ }
+}
diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/jetty/Jetty9Handler.java b/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/jetty/Jetty9Handler.java
index be1a10183..5946f52a7 100644
--- a/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/jetty/Jetty9Handler.java
+++ b/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/jetty/Jetty9Handler.java
@@ -17,6 +17,8 @@
package org.dromara.hutool.http.server.engine.jetty;
import org.dromara.hutool.http.server.handler.HttpHandler;
+import org.dromara.hutool.http.server.servlet.JavaxServletRequest;
+import org.dromara.hutool.http.server.servlet.JavaxServletResponse;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
@@ -44,6 +46,6 @@ public class Jetty9Handler extends AbstractHandler {
@Override
public void handle(final String target, final Request baseRequest,
final HttpServletRequest request, final HttpServletResponse response) {
- handler.handle(new Jetty9Request(request), new Jetty9Response(response));
+ handler.handle(new JavaxServletRequest(request), new JavaxServletResponse(response));
}
}
diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/sun/SunHttpServerEngine.java b/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/sun/SunHttpServerEngine.java
index 53ad8fdd9..ce9f22981 100644
--- a/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/sun/SunHttpServerEngine.java
+++ b/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/sun/SunHttpServerEngine.java
@@ -17,6 +17,7 @@
package org.dromara.hutool.http.server.engine.sun;
import com.sun.net.httpserver.*;
+import org.dromara.hutool.core.collection.CollUtil;
import org.dromara.hutool.core.io.IORuntimeException;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.thread.GlobalThreadPool;
@@ -115,7 +116,9 @@ public class SunHttpServerEngine extends AbstractServerEngine {
path = StrUtil.addPrefixIfNot(path, StrUtil.SLASH);
final HttpContext context = this.server.createContext(path, handler);
// 增加整体过滤器
- context.getFilters().addAll(this.filters);
+ if(CollUtil.isNotEmpty(this.filters)){
+ context.getFilters().addAll(this.filters);
+ }
return context;
}
diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/tomcat/TomcatEngine.java b/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/tomcat/TomcatEngine.java
new file mode 100644
index 000000000..1eabc5081
--- /dev/null
+++ b/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/tomcat/TomcatEngine.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2024 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.dromara.hutool.http.server.engine.tomcat;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.catalina.startup.Tomcat;
+import org.apache.catalina.valves.ValveBase;
+import org.dromara.hutool.core.lang.Assert;
+import org.dromara.hutool.http.HttpException;
+import org.dromara.hutool.http.server.engine.AbstractServerEngine;
+
+/**
+ * Tomcat引擎实现
+ *
+ * @author Looly
+ * @since 6.0.0
+ */
+public class TomcatEngine extends AbstractServerEngine {
+
+ private Tomcat tomcat;
+
+ /**
+ * 构造
+ */
+ public TomcatEngine() {
+ // issue#IABWBL JDK8下,在IDEA旗舰版加载Spring boot插件时,启动应用不会检查字段类是否存在
+ // 此处构造时调用下这个类,以便触发类是否存在的检查
+ Assert.notNull(Tomcat.class);
+ // 初始化过程中遇到任何严重错误时会立即退出
+ System.setProperty("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE", "true");
+ }
+
+ @Override
+ public void start() {
+ initEngine();
+ try {
+ this.tomcat.start();
+ } catch (final LifecycleException e) {
+ throw new HttpException(e);
+ }
+ // 阻塞
+ tomcat.getServer().await();
+ }
+
+ @Override
+ public Tomcat getRawEngine() {
+ return this.tomcat;
+ }
+
+ @Override
+ protected void reset() {
+ if (null != this.tomcat) {
+ try {
+ this.tomcat.destroy();
+ } catch (final LifecycleException e) {
+ throw new HttpException(e);
+ }
+ this.tomcat = null;
+ }
+ }
+
+ @Override
+ protected void initEngine() {
+ if (null != this.tomcat) {
+ return;
+ }
+
+ final Tomcat tomcat = new Tomcat();
+ tomcat.setHostname(this.config.getHost());
+ tomcat.setPort(this.config.getPort());
+ tomcat.setBaseDir(this.config.getRoot());
+
+ initContext(tomcat);
+
+ this.tomcat = tomcat;
+ }
+
+ /**
+ * 初始化Context
+ *
+ * @param tomcat Tomcat
+ */
+ private void initContext(final Tomcat tomcat) {
+ final Context context = tomcat.addContext("/", this.config.getRoot());
+ context.getPipeline().addValve(new ValveBase() {
+ @Override
+ public void invoke(final Request request, final Response response) {
+ handler.handle(new TomcatRequest(request), new TomcatResponse(response));
+ }
+
+ // 此处拦截所有请求,无需调用getNext
+ });
+ }
+}
diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/tomcat/TomcatRequest.java b/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/tomcat/TomcatRequest.java
new file mode 100644
index 000000000..1e6974531
--- /dev/null
+++ b/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/tomcat/TomcatRequest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2024 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.dromara.hutool.http.server.engine.tomcat;
+
+import org.apache.catalina.connector.Request;
+import org.dromara.hutool.http.server.handler.ServerRequest;
+
+import java.io.InputStream;
+
+/**
+ * Tomcat请求对象包装
+ *
+ * @author Looly
+ * @since 6.0.0
+ */
+public class TomcatRequest implements ServerRequest {
+
+ private final Request request;
+
+ /**
+ * 构造
+ *
+ * @param request Tomcat请求对象
+ */
+ public TomcatRequest(final Request request) {
+ this.request = request;
+ }
+
+ @Override
+ public String getMethod() {
+ return request.getMethod();
+ }
+
+ @Override
+ public String getPath() {
+ return request.getContextPath();
+ }
+
+ @Override
+ public String getQuery() {
+ return request.getQueryString();
+ }
+
+ @Override
+ public String getHeader(final String name) {
+ return request.getHeader(name);
+ }
+
+ @Override
+ public InputStream getBodyStream() {
+ return request.getStream();
+ }
+}
diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/jetty/Jetty9Response.java b/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/tomcat/TomcatResponse.java
similarity index 70%
rename from hutool-http/src/main/java/org/dromara/hutool/http/server/engine/jetty/Jetty9Response.java
rename to hutool-http/src/main/java/org/dromara/hutool/http/server/engine/tomcat/TomcatResponse.java
index 99b30d502..48fb28747 100644
--- a/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/jetty/Jetty9Response.java
+++ b/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/tomcat/TomcatResponse.java
@@ -14,43 +14,44 @@
* limitations under the License.
*/
-package org.dromara.hutool.http.server.engine.jetty;
+package org.dromara.hutool.http.server.engine.tomcat;
+import org.apache.catalina.connector.Response;
import org.dromara.hutool.core.io.IORuntimeException;
import org.dromara.hutool.http.server.handler.ServerResponse;
-import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
/**
- * Jetty响应对象包装
+ * Tomcat响应对象包装
*
* @author Looly
+ * @since 6.0.0
*/
-public class Jetty9Response implements ServerResponse {
+public class TomcatResponse implements ServerResponse {
- private final HttpServletResponse response;
+ private final Response response;
private Charset charset;
/**
* 构造
*
- * @param response Jetty响应对象
+ * @param response Tomcat响应对象
*/
- public Jetty9Response(final HttpServletResponse response) {
+ public TomcatResponse(final Response response) {
this.response = response;
}
@Override
- public Jetty9Response setStatus(final int statusCode) {
- this.response.setStatus(statusCode);
+ public TomcatResponse setStatus(final int statusCode) {
+ response.setStatus(statusCode);
return this;
}
@Override
- public Jetty9Response setCharset(final Charset charset) {
+ public TomcatResponse setCharset(final Charset charset) {
this.charset = charset;
return this;
}
@@ -61,13 +62,13 @@ public class Jetty9Response implements ServerResponse {
}
@Override
- public Jetty9Response addHeader(final String header, final String value) {
+ public TomcatResponse addHeader(final String header, final String value) {
this.response.addHeader(header, value);
return this;
}
@Override
- public Jetty9Response setHeader(final String header, final String value) {
+ public TomcatResponse setHeader(final String header, final String value) {
this.response.setHeader(header, value);
return this;
}
diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/jetty/Jetty9Request.java b/hutool-http/src/main/java/org/dromara/hutool/http/server/servlet/JavaxServletRequest.java
similarity index 69%
rename from hutool-http/src/main/java/org/dromara/hutool/http/server/engine/jetty/Jetty9Request.java
rename to hutool-http/src/main/java/org/dromara/hutool/http/server/servlet/JavaxServletRequest.java
index b4eea65d3..d16c039f3 100644
--- a/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/jetty/Jetty9Request.java
+++ b/hutool-http/src/main/java/org/dromara/hutool/http/server/servlet/JavaxServletRequest.java
@@ -14,20 +14,22 @@
* limitations under the License.
*/
-package org.dromara.hutool.http.server.engine.jetty;
+package org.dromara.hutool.http.server.servlet;
import org.dromara.hutool.http.server.handler.ServerRequest;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
/**
- * Jetty请求对象包装
+ * Javax Servlet请求对象包装
*
* @author Looly
*/
-public class Jetty9Request implements ServerRequest {
+public class JavaxServletRequest implements ServerRequest {
private final HttpServletRequest request;
@@ -36,7 +38,7 @@ public class Jetty9Request implements ServerRequest {
*
* @param request Jetty请求对象
*/
- public Jetty9Request(final HttpServletRequest request) {
+ public JavaxServletRequest(final HttpServletRequest request) {
this.request = request;
}
@@ -55,6 +57,24 @@ public class Jetty9Request implements ServerRequest {
return this.request.getQueryString();
}
+ /**
+ * 获取所有请求头
+ *
+ * @return 请求头Map
+ */
+ public Map getHeaderMap(){
+ return JavaxServletUtil.getHeaderMap(this.request);
+ }
+
+ /**
+ * 获取所有请求头,包括多个相同名称的请求头
+ *
+ * @return 请求头Map
+ */
+ public Map> getHeadersMap(){
+ return JavaxServletUtil.getHeadersMap(this.request);
+ }
+
@Override
public String getHeader(final String name) {
return this.request.getHeader(name);
diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/server/servlet/JavaxServletResponse.java b/hutool-http/src/main/java/org/dromara/hutool/http/server/servlet/JavaxServletResponse.java
new file mode 100644
index 000000000..bd1510cab
--- /dev/null
+++ b/hutool-http/src/main/java/org/dromara/hutool/http/server/servlet/JavaxServletResponse.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2024 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.dromara.hutool.http.server.servlet;
+
+import org.dromara.hutool.core.io.IORuntimeException;
+import org.dromara.hutool.http.server.handler.ServerResponse;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+
+/**
+ * Javax Jetty响应对象包装
+ *
+ * @author Looly
+ */
+public class JavaxServletResponse implements ServerResponse {
+
+ private final HttpServletResponse response;
+ private Charset charset;
+
+ /**
+ * 构造
+ *
+ * @param response Jetty响应对象
+ */
+ public JavaxServletResponse(final HttpServletResponse response) {
+ this.response = response;
+ }
+
+ @Override
+ public JavaxServletResponse setStatus(final int statusCode) {
+ this.response.setStatus(statusCode);
+ return this;
+ }
+
+ @Override
+ public JavaxServletResponse setCharset(final Charset charset) {
+ this.charset = charset;
+ return this;
+ }
+
+ @Override
+ public Charset getCharset() {
+ return this.charset;
+ }
+
+ @Override
+ public JavaxServletResponse addHeader(final String header, final String value) {
+ this.response.addHeader(header, value);
+ return this;
+ }
+
+ @Override
+ public JavaxServletResponse setHeader(final String header, final String value) {
+ this.response.setHeader(header, value);
+ return this;
+ }
+
+ /**
+ * 增加Cookie
+ *
+ * @param cookie Cookie对象
+ * @return this
+ */
+ public JavaxServletResponse addCookie(final Cookie cookie){
+ JavaxServletUtil.addCookie(this.response, cookie);
+ return this;
+ }
+
+ @Override
+ public OutputStream getOutputStream() {
+ try {
+ return this.response.getOutputStream();
+ } catch (final IOException e) {
+ throw new IORuntimeException(e);
+ }
+ }
+}
diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/server/servlet/ServletRequest.java b/hutool-http/src/main/java/org/dromara/hutool/http/server/servlet/ServletRequest.java
new file mode 100644
index 000000000..3ffccdbc4
--- /dev/null
+++ b/hutool-http/src/main/java/org/dromara/hutool/http/server/servlet/ServletRequest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2024 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.dromara.hutool.http.server.servlet;
+
+import jakarta.servlet.http.HttpServletRequest;
+import org.dromara.hutool.http.server.handler.ServerRequest;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Jakarta Servlet请求对象包装
+ *
+ * @author Looly
+ */
+public class ServletRequest implements ServerRequest {
+
+ private final HttpServletRequest request;
+
+ /**
+ * 构造
+ *
+ * @param request Jetty请求对象
+ */
+ public ServletRequest(final HttpServletRequest request) {
+ this.request = request;
+ }
+
+ @Override
+ public String getMethod() {
+ return this.request.getMethod();
+ }
+
+ @Override
+ public String getPath() {
+ return this.request.getContextPath();
+ }
+
+ @Override
+ public String getQuery() {
+ return this.request.getQueryString();
+ }
+
+ /**
+ * 获取所有请求头
+ *
+ * @return 请求头Map
+ */
+ public Map getHeaderMap(){
+ return ServletUtil.getHeaderMap(this.request);
+ }
+
+ /**
+ * 获取所有请求头,包括多个相同名称的请求头
+ *
+ * @return 请求头Map
+ */
+ public Map> getHeadersMap(){
+ return ServletUtil.getHeadersMap(this.request);
+ }
+
+ @Override
+ public String getHeader(final String name) {
+ return this.request.getHeader(name);
+ }
+
+ @Override
+ public InputStream getBodyStream() {
+ try {
+ return this.request.getInputStream();
+ } catch (final IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/server/servlet/ServletResponse.java b/hutool-http/src/main/java/org/dromara/hutool/http/server/servlet/ServletResponse.java
new file mode 100644
index 000000000..8b283ad03
--- /dev/null
+++ b/hutool-http/src/main/java/org/dromara/hutool/http/server/servlet/ServletResponse.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2024 Hutool Team and hutool.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.dromara.hutool.http.server.servlet;
+
+import jakarta.servlet.http.Cookie;
+import jakarta.servlet.http.HttpServletResponse;
+import org.dromara.hutool.core.io.IORuntimeException;
+import org.dromara.hutool.http.server.handler.ServerResponse;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+
+/**
+ * Jakarta Servlet响应对象包装
+ *
+ * @author Looly
+ */
+public class ServletResponse implements ServerResponse {
+
+ private final HttpServletResponse response;
+ private Charset charset;
+
+ /**
+ * 构造
+ *
+ * @param response Jetty响应对象
+ */
+ public ServletResponse(final HttpServletResponse response) {
+ this.response = response;
+ }
+
+ @Override
+ public ServletResponse setStatus(final int statusCode) {
+ this.response.setStatus(statusCode);
+ return this;
+ }
+
+ @Override
+ public ServletResponse setCharset(final Charset charset) {
+ this.charset = charset;
+ return this;
+ }
+
+ @Override
+ public Charset getCharset() {
+ return this.charset;
+ }
+
+ @Override
+ public ServletResponse addHeader(final String header, final String value) {
+ this.response.addHeader(header, value);
+ return this;
+ }
+
+ @Override
+ public ServletResponse setHeader(final String header, final String value) {
+ this.response.setHeader(header, value);
+ return this;
+ }
+
+ /**
+ * 增加Cookie
+ *
+ * @param cookie Cookie对象
+ * @return this
+ */
+ public ServletResponse addCookie(final Cookie cookie){
+ ServletUtil.addCookie(this.response, cookie);
+ return this;
+ }
+
+ @Override
+ public OutputStream getOutputStream() {
+ try {
+ return this.response.getOutputStream();
+ } catch (final IOException e) {
+ throw new IORuntimeException(e);
+ }
+ }
+}
diff --git a/hutool-http/src/main/resources/META-INF/services/org.dromara.hutool.http.server.engine.ServerEngine b/hutool-http/src/main/resources/META-INF/services/org.dromara.hutool.http.server.engine.ServerEngine
new file mode 100644
index 000000000..077c0e02d
--- /dev/null
+++ b/hutool-http/src/main/resources/META-INF/services/org.dromara.hutool.http.server.engine.ServerEngine
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2024 Hutool Team and hutool.cn
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+org.dromara.hutool.http.server.engine.undertow.UndertowEngine
+org.dromara.hutool.http.server.engine.tomcat.TomcatEngine
+org.dromara.hutool.http.server.engine.jetty.JettyEngine
+org.dromara.hutool.http.server.engine.sun.SunHttpServerEngine
diff --git a/hutool-http/src/test/java/org/dromara/hutool/http/server/engine/JettyTest.java b/hutool-http/src/test/java/org/dromara/hutool/http/server/engine/JettyTest.java
index 0ca81ef8e..065457007 100644
--- a/hutool-http/src/test/java/org/dromara/hutool/http/server/engine/JettyTest.java
+++ b/hutool-http/src/test/java/org/dromara/hutool/http/server/engine/JettyTest.java
@@ -2,11 +2,10 @@ package org.dromara.hutool.http.server.engine;
import org.dromara.hutool.core.lang.Console;
import org.dromara.hutool.http.server.ServerConfig;
-import org.dromara.hutool.http.server.engine.jetty.JettyEngine;
public class JettyTest {
public static void main(String[] args) {
- final JettyEngine engine = new JettyEngine();
+ final ServerEngine engine = ServerEngineFactory.createEngine("jetty");
engine.init(ServerConfig.of());
engine.setHandler((request, response) -> {
Console.log(request.getPath());
diff --git a/hutool-http/src/test/java/org/dromara/hutool/http/server/engine/SunServerTest.java b/hutool-http/src/test/java/org/dromara/hutool/http/server/engine/SunServerTest.java
new file mode 100644
index 000000000..4bd464276
--- /dev/null
+++ b/hutool-http/src/test/java/org/dromara/hutool/http/server/engine/SunServerTest.java
@@ -0,0 +1,16 @@
+package org.dromara.hutool.http.server.engine;
+
+import org.dromara.hutool.core.lang.Console;
+import org.dromara.hutool.http.server.ServerConfig;
+
+public class SunServerTest {
+ public static void main(String[] args) {
+ final ServerEngine engine = ServerEngineFactory.createEngine("SunHttpServer");
+ engine.init(ServerConfig.of());
+ engine.setHandler((request, response) -> {
+ Console.log(request.getPath());
+ response.write("Hutool Sun Server response test");
+ });
+ engine.start();
+ }
+}
diff --git a/hutool-http/src/test/java/org/dromara/hutool/http/server/engine/TomcatTest.java b/hutool-http/src/test/java/org/dromara/hutool/http/server/engine/TomcatTest.java
new file mode 100644
index 000000000..a567923af
--- /dev/null
+++ b/hutool-http/src/test/java/org/dromara/hutool/http/server/engine/TomcatTest.java
@@ -0,0 +1,16 @@
+package org.dromara.hutool.http.server.engine;
+
+import org.dromara.hutool.core.lang.Console;
+import org.dromara.hutool.http.server.ServerConfig;
+
+public class TomcatTest {
+ public static void main(String[] args) {
+ final ServerEngine engine = ServerEngineFactory.createEngine("tomcat");
+ engine.init(ServerConfig.of());
+ engine.setHandler((request, response) -> {
+ Console.log(request.getPath());
+ response.write("Hutool Tomcat response test");
+ });
+ engine.start();
+ }
+}
diff --git a/hutool-http/src/test/java/org/dromara/hutool/http/server/engine/UndertowTest.java b/hutool-http/src/test/java/org/dromara/hutool/http/server/engine/UndertowTest.java
index d9e82d043..1b5ae94a7 100644
--- a/hutool-http/src/test/java/org/dromara/hutool/http/server/engine/UndertowTest.java
+++ b/hutool-http/src/test/java/org/dromara/hutool/http/server/engine/UndertowTest.java
@@ -18,11 +18,10 @@ package org.dromara.hutool.http.server.engine;
import org.dromara.hutool.core.lang.Console;
import org.dromara.hutool.http.server.ServerConfig;
-import org.dromara.hutool.http.server.engine.undertow.UndertowEngine;
public class UndertowTest {
public static void main(String[] args) {
- final UndertowEngine engine = new UndertowEngine();
+ final ServerEngine engine = ServerEngineFactory.createEngine("undertow");
engine.init(ServerConfig.of());
engine.setHandler((request, response) -> {
Console.log(request.getPath());