From 7f12d45b4e8c34c1dd4074b4a59ae831ff4c172b Mon Sep 17 00:00:00 2001 From: Looly Date: Wed, 25 Dec 2024 14:20:24 +0800 Subject: [PATCH] add smart http support --- .../hutool/core/cache/impl/FIFOCache.java | 4 +- .../hutool/core/cache/impl/LFUCache.java | 11 +- .../hutool/core/cache/impl/LRUCache.java | 4 +- .../{ReentrantCache.java => LockedCache.java} | 8 +- .../hutool/core/cache/impl/StampedCache.java | 203 ------------------ .../hutool/core/cache/impl/TimedCache.java | 12 +- .../core/cache/impl/TimedReentrantCache.java | 2 +- .../hutool/core/cache/impl/WeakCache.java | 4 +- hutool-http/pom.xml | 7 + .../server/engine/smart/SmartHttpRequest.java | 83 +++++++ .../engine/smart/SmartHttpResponse.java | 79 +++++++ .../engine/smart/SmartHttpServerEngine.java | 112 ++++++++++ .../server/engine/smart/package-info.java | 24 +++ ...ara.hutool.http.server.engine.ServerEngine | 1 + .../server/engine/SmartHttpServerTest.java | 27 +++ 15 files changed, 362 insertions(+), 219 deletions(-) rename hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/{ReentrantCache.java => LockedCache.java} (91%) delete mode 100644 hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/StampedCache.java create mode 100644 hutool-http/src/main/java/org/dromara/hutool/http/server/engine/smart/SmartHttpRequest.java create mode 100644 hutool-http/src/main/java/org/dromara/hutool/http/server/engine/smart/SmartHttpResponse.java create mode 100644 hutool-http/src/main/java/org/dromara/hutool/http/server/engine/smart/SmartHttpServerEngine.java create mode 100644 hutool-http/src/main/java/org/dromara/hutool/http/server/engine/smart/package-info.java create mode 100644 hutool-http/src/test/java/org/dromara/hutool/http/server/engine/SmartHttpServerTest.java diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/FIFOCache.java b/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/FIFOCache.java index 888d5e297..9b17fedfa 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/FIFOCache.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/FIFOCache.java @@ -34,7 +34,7 @@ import java.util.LinkedHashMap; * @param 值类型 * @author Looly */ -public class FIFOCache extends ReentrantCache { +public class FIFOCache extends LockedCache { private static final long serialVersionUID = 1L; /** @@ -55,7 +55,7 @@ public class FIFOCache extends ReentrantCache { public FIFOCache(final int capacity, final long timeout) { this.capacity = capacity; this.timeout = timeout; - cacheMap = new LinkedHashMap<>(capacity + 1, 1.0f, false); + this.cacheMap = new LinkedHashMap<>(capacity + 1, 1.0f, false); } /** diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/LFUCache.java b/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/LFUCache.java index 97099d793..195359885 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/LFUCache.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/LFUCache.java @@ -16,8 +16,10 @@ package org.dromara.hutool.core.cache.impl; -import java.util.HashMap; +import org.dromara.hutool.core.thread.lock.NoLock; + import java.util.Iterator; +import java.util.concurrent.ConcurrentHashMap; /** * LFU(least frequently used) 最少使用率缓存
@@ -31,7 +33,7 @@ import java.util.Iterator; * @param 键类型 * @param 值类型 */ -public class LFUCache extends StampedCache { +public class LFUCache extends LockedCache { private static final long serialVersionUID = 1L; /** @@ -56,7 +58,10 @@ public class LFUCache extends StampedCache { this.capacity = capacity; this.timeout = timeout; - cacheMap = new HashMap<>(capacity + 1, 1.0f); + //lock = new ReentrantLock(); + //cacheMap = new HashMap<>(capacity + 1, 1.0f); + lock = NoLock.INSTANCE; + cacheMap = new ConcurrentHashMap<>(capacity + 1, 1.0f); } // ---------------------------------------------------------------- prune diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/LRUCache.java b/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/LRUCache.java index 2000764bc..800fbb058 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/LRUCache.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/LRUCache.java @@ -20,6 +20,7 @@ import org.dromara.hutool.core.lang.mutable.Mutable; import org.dromara.hutool.core.map.FixedLinkedHashMap; import java.util.Iterator; +import java.util.concurrent.locks.ReentrantLock; /** * LRU (least recently used)最近最久未使用缓存
@@ -33,7 +34,7 @@ import java.util.Iterator; * @param 键类型 * @param 值类型 */ -public class LRUCache extends ReentrantCache { +public class LRUCache extends LockedCache { private static final long serialVersionUID = 1L; /** @@ -65,6 +66,7 @@ public class LRUCache extends ReentrantCache { listener.onRemove(entry.getKey().get(), entry.getValue().getValue()); } }); + lock = new ReentrantLock(); cacheMap = fixedLinkedHashMap; } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/ReentrantCache.java b/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/LockedCache.java similarity index 91% rename from hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/ReentrantCache.java rename to hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/LockedCache.java index 25a789bc8..928824082 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/ReentrantCache.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/LockedCache.java @@ -19,24 +19,24 @@ package org.dromara.hutool.core.cache.impl; import org.dromara.hutool.core.collection.iter.CopiedIter; import java.util.Iterator; +import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** - * 使用{@link ReentrantLock}保护的缓存,读写都使用悲观锁完成,主要避免某些Map无法使用读写锁的问题
+ * 使用{@link Lock}保护的缓存,读写都使用悲观锁完成,主要避免某些Map无法使用读写锁的问题
* 例如使用了LinkedHashMap的缓存,由于get方法也会改变Map的结构,因此读写必须加互斥锁 * * @param 键类型 * @param 值类型 * @author looly - * @since 5.7.15 */ -public abstract class ReentrantCache extends AbstractCache { +public abstract class LockedCache extends AbstractCache { private static final long serialVersionUID = 1L; /** * 一些特殊缓存,例如使用了LinkedHashMap的缓存,由于get方法也会改变Map的结构,导致无法使用读写锁 */ - protected final ReentrantLock lock = new ReentrantLock(); + protected Lock lock = new ReentrantLock(); @Override public void put(final K key, final V object, final long timeout) { diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/StampedCache.java b/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/StampedCache.java deleted file mode 100644 index 04a3b563c..000000000 --- a/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/StampedCache.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * 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.core.cache.impl; - -import org.dromara.hutool.core.collection.iter.CopiedIter; - -import java.util.Iterator; -import java.util.concurrent.locks.StampedLock; - -/** - * 使用{@link StampedLock}保护的缓存,使用读写乐观锁
- * 使用乐观锁有效的提高的缓存性能,但是无法避免脏读问题 - * - * @param 键类型 - * @param 值类型 - * @author looly - * @since 5.7.15 - */ -public abstract class StampedCache extends AbstractCache { - private static final long serialVersionUID = 1L; - - /** - * 乐观锁,此处使用乐观锁解决读多写少的场景
- * get时乐观读,再检查是否修改,修改则转入悲观读重新读一遍,可以有效解决在写时阻塞大量读操作的情况。
- * see: https://www.cnblogs.com/jiagoushijuzi/p/13721319.html - */ - protected final StampedLock lock = new StampedLock(); - - @Override - public void put(final K key, final V object, final long timeout) { - final long stamp = lock.writeLock(); - try { - putWithoutLock(key, object, timeout); - } finally { - lock.unlockWrite(stamp); - } - } - - @Override - public boolean containsKey(final K key) { - return null != doGet(key, false, false); - } - - @Override - public V get(final K key, final boolean isUpdateLastAccess) { - return doGet(key, isUpdateLastAccess, true); - } - - @Override - public Iterator> cacheObjIterator() { - CopiedIter> copiedIterator; - final long stamp = lock.readLock(); - try { - copiedIterator = CopiedIter.copyOf(cacheObjIter()); - } finally { - lock.unlockRead(stamp); - } - return new CacheObjIterator<>(copiedIterator); - } - - @Override - public final int prune() { - final long stamp = lock.writeLock(); - try { - return pruneCache(); - } finally { - lock.unlockWrite(stamp); - } - } - - @Override - public void remove(final K key) { - final long stamp = lock.writeLock(); - CacheObj co; - try { - co = removeWithoutLock(key); - } finally { - lock.unlockWrite(stamp); - } - if (null != co) { - onRemove(co.key, co.obj); - } - } - - @Override - public void clear() { - final long stamp = lock.writeLock(); - try { - cacheMap.clear(); - } finally { - lock.unlockWrite(stamp); - } - } - - /** - * 获取值,使用乐观锁,但是此方法可能导致读取脏数据,但对于缓存业务可容忍。情况如下: - *
-	 *     1. 读取时无写入,不冲突,直接获取值
-	 *     2. 读取时无写入,但是乐观读时触发了并发异常,此时获取同步锁,获取新值
-	 *     3. 读取时有写入,此时获取同步锁,获取新值
-	 * 
- * - * @param key 键 - * @param isUpdateLastAccess 是否更新最后修改时间 - * @param isUpdateCount 是否更新命中数,get时更新,contains时不更新 - * @return 值或null - */ - private V doGet(final K key, final boolean isUpdateLastAccess, final boolean isUpdateCount) { - // 尝试读取缓存,使用乐观读锁 - CacheObj co = null; - long stamp = lock.tryOptimisticRead(); - boolean isReadError = true; - if(lock.validate(stamp)){ - try{ - // 乐观读,可能读取脏数据,在缓存中可容忍,分两种情况 - // 1. 读取时无线程写入 - // 2. 读取时有线程写入,导致数据不一致,此时读取未更新的缓存值 - co = getWithoutLock(key); - isReadError = false; - } catch (final Exception ignore){ - // ignore - } - } - - if(isReadError){ - // 转换为悲观读 - // 原因可能为无锁读时触发并发异常,或者锁被占(正在写) - stamp = lock.readLock(); - try { - co = getWithoutLock(key); - } finally { - lock.unlockRead(stamp); - } - } - - // 未命中 - if (null == co) { - if (isUpdateCount) { - missCount.increment(); - } - return null; - } else if (!co.isExpired()) { - if (isUpdateCount) { - hitCount.increment(); - } - return co.get(isUpdateLastAccess); - } - - // 悲观锁,二次检查 - return getOrRemoveExpired(key, isUpdateCount); - } - - /** - * 同步获取值,如果过期则移除之 - * - * @param key 键 - * @param isUpdateCount 是否更新命中数,get时更新,contains时不更新 - * @return 有效值或null - */ - private V getOrRemoveExpired(final K key, final boolean isUpdateCount) { - final long stamp = lock.writeLock(); - CacheObj co; - try { - co = getWithoutLock(key); - if (null == co) { - return null; - } - if (!co.isExpired()) { - // 首先尝试获取值,如果值存在且有效,返回之 - if (isUpdateCount) { - hitCount.increment(); - } - return co.getValue(); - } - - // 无效移除 - co = removeWithoutLock(key); - if (isUpdateCount) { - missCount.increment(); - } - } finally { - lock.unlockWrite(stamp); - } - if (null != co) { - onRemove(co.key, co.obj); - } - return null; - } -} diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/TimedCache.java b/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/TimedCache.java index 80f30cefa..ac18f241e 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/TimedCache.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/TimedCache.java @@ -19,9 +19,15 @@ package org.dromara.hutool.core.cache.impl; import org.dromara.hutool.core.cache.GlobalPruneTimer; import org.dromara.hutool.core.lang.Assert; import org.dromara.hutool.core.lang.mutable.Mutable; +import org.dromara.hutool.core.thread.lock.NoLock; -import java.util.*; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.locks.ReentrantLock; /** * 定时缓存
@@ -33,7 +39,7 @@ import java.util.concurrent.ScheduledFuture; * @param 键类型 * @param 值类型 */ -public class TimedCache extends StampedCache { +public class TimedCache extends LockedCache { private static final long serialVersionUID = 1L; /** 正在执行的定时任务 */ @@ -57,6 +63,8 @@ public class TimedCache extends StampedCache { public TimedCache(final long timeout, final Map, CacheObj> map) { this.capacity = 0; this.timeout = timeout; + // 如果使用线程安全的Map,则不加锁,否则默认使用ReentrantLock + this.lock = map instanceof ConcurrentMap ? NoLock.INSTANCE : new ReentrantLock(); this.cacheMap = Assert.isNotInstanceOf(LinkedHashMap.class, map); } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/TimedReentrantCache.java b/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/TimedReentrantCache.java index 0f0112f3d..ad2766aab 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/TimedReentrantCache.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/TimedReentrantCache.java @@ -33,7 +33,7 @@ import java.util.concurrent.ScheduledFuture; * @param 键类型 * @param 值类型 */ -public class TimedReentrantCache extends ReentrantCache { +public class TimedReentrantCache extends LockedCache { private static final long serialVersionUID = 1L; /** 正在执行的定时任务 */ diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/WeakCache.java b/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/WeakCache.java index ecb6534dc..d968b99cf 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/WeakCache.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/WeakCache.java @@ -22,8 +22,6 @@ import org.dromara.hutool.core.lang.mutable.Mutable; import org.dromara.hutool.core.lang.ref.Ref; import org.dromara.hutool.core.map.reference.WeakConcurrentMap; -import java.util.WeakHashMap; - /** * 弱引用缓存
* 对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的丢弃,这就使该键成为可终止的,被终止,然后被回收。
@@ -44,7 +42,7 @@ public class WeakCache extends TimedCache{ * @param timeout 超时时常,单位毫秒,-1或0表示无限制 */ public WeakCache(final long timeout) { - super(timeout, new WeakHashMap<>()); + super(timeout, new WeakConcurrentMap<>()); } @Override diff --git a/hutool-http/pom.xml b/hutool-http/pom.xml index 371393a09..d5e4c0a41 100755 --- a/hutool-http/pom.xml +++ b/hutool-http/pom.xml @@ -43,6 +43,7 @@ 9.4.56.v20240826 9.0.97 + 1.4.3 @@ -131,6 +132,12 @@ ${tomcat.version} provided + + org.smartboot.http + smart-http-server + ${smartboot.version} + provided + diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/smart/SmartHttpRequest.java b/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/smart/SmartHttpRequest.java new file mode 100644 index 000000000..bcac3fe54 --- /dev/null +++ b/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/smart/SmartHttpRequest.java @@ -0,0 +1,83 @@ +/* + * 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.smart; + +import org.dromara.hutool.core.io.IORuntimeException; +import org.dromara.hutool.http.server.handler.ServerRequest; +import org.smartboot.http.server.HttpRequest; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Collection; + +/** + * SmartHttp请求对象 + * + * @author looly + * @since 6.0.0 + */ +public class SmartHttpRequest implements ServerRequest { + + private final HttpRequest request; + + /** + * 构造 + * + * @param request 请求对象 + */ + public SmartHttpRequest(final HttpRequest request) { + this.request = request; + } + + @Override + public String getMethod() { + return request.getMethod(); + } + + @Override + public String getPath() { + return request.getRequestURI(); + } + + @Override + public String getQuery() { + return request.getQueryString(); + } + + @Override + public String getHeader(final String name) { + return request.getHeader(name); + } + + /** + * 获取所有Header名称 + * + * @return 所有Header名称 + */ + public Collection getHeaderNames() { + return request.getHeaderNames(); + } + + @Override + public InputStream getBodyStream() { + try { + return request.getInputStream(); + } catch (final IOException e) { + throw new IORuntimeException(e); + } + } +} diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/smart/SmartHttpResponse.java b/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/smart/SmartHttpResponse.java new file mode 100644 index 000000000..734400c45 --- /dev/null +++ b/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/smart/SmartHttpResponse.java @@ -0,0 +1,79 @@ +/* + * 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.smart; + +import org.dromara.hutool.http.server.handler.ServerResponse; +import org.smartboot.http.common.enums.HttpStatus; +import org.smartboot.http.server.HttpResponse; + +import java.io.OutputStream; +import java.nio.charset.Charset; + +/** + * SmartHttp响应对象 + * + * @author Looly + * @since 6.0.0 + */ +public class SmartHttpResponse implements ServerResponse { + + private final HttpResponse response; + private Charset charset; + + /** + * 构造 + * + * @param response 响应对象 + */ + public SmartHttpResponse(final HttpResponse response) { + this.response = response; + } + + @Override + public SmartHttpResponse setStatus(final int statusCode) { + response.setHttpStatus(HttpStatus.valueOf(statusCode)); + return this; + } + + @Override + public SmartHttpResponse setCharset(final Charset charset) { + this.charset = charset; + return this; + } + + @Override + public Charset getCharset() { + return this.charset; + } + + @Override + public SmartHttpResponse addHeader(final String header, final String value) { + this.response.addHeader(header, value); + return this; + } + + @Override + public SmartHttpResponse setHeader(final String header, final String value) { + this.response.setHeader(header, value); + return this; + } + + @Override + public OutputStream getOutputStream() { + return this.response.getOutputStream(); + } +} diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/smart/SmartHttpServerEngine.java b/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/smart/SmartHttpServerEngine.java new file mode 100644 index 000000000..ece3082dc --- /dev/null +++ b/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/smart/SmartHttpServerEngine.java @@ -0,0 +1,112 @@ +/* + * 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.smart; + +import org.dromara.hutool.core.lang.Assert; +import org.dromara.hutool.http.HttpException; +import org.dromara.hutool.http.server.ServerConfig; +import org.dromara.hutool.http.server.engine.AbstractServerEngine; +import org.smartboot.http.server.*; +import org.smartboot.http.server.impl.Request; +import org.smartboot.socket.extension.plugins.SslPlugin; + +import javax.net.ssl.SSLContext; + +/** + * smart-http-server引擎 + * + * @author looly + * @since 6.0.0 + */ +public class SmartHttpServerEngine extends AbstractServerEngine { + + private HttpBootstrap bootstrap; + + /** + * 构造 + */ + public SmartHttpServerEngine() { + // issue#IABWBL JDK8下,在IDEA旗舰版加载Spring boot插件时,启动应用不会检查字段类是否存在 + // 此处构造时调用下这个类,以便触发类是否存在的检查 + Assert.notNull(HttpBootstrap.class); + } + + @Override + public void start() { + initEngine(); + bootstrap.start(); + } + + @Override + public HttpBootstrap getRawEngine() { + return this.bootstrap; + } + + @Override + protected void reset() { + if(null != this.bootstrap){ + this.bootstrap.shutdown(); + this.bootstrap = null; + } + } + + @Override + protected void initEngine() { + if (null != this.bootstrap) { + return; + } + + final HttpBootstrap bootstrap = new HttpBootstrap(); + final HttpServerConfiguration configuration = bootstrap.configuration(); + + final ServerConfig config = this.config; + configuration.host(config.getHost()); + + // SSL + final SSLContext sslContext = config.getSslContext(); + if(null != sslContext){ + final SslPlugin sslPlugin; + try { + sslPlugin = new SslPlugin<>(() -> sslContext); + } catch (final Exception e) { + throw new HttpException(e); + } + configuration.addPlugin(sslPlugin); + } + + // 选项 + final int coreThreads = config.getCoreThreads(); + if(coreThreads > 0){ + configuration.threadNum(coreThreads); + } + + final long idleTimeout = config.getIdleTimeout(); + if(idleTimeout > 0){ + configuration.setHttpIdleTimeout((int) idleTimeout); + } + + bootstrap.httpHandler(new HttpServerHandler() { + @Override + public void handle(final HttpRequest request, final HttpResponse response) { + handler.handle(new SmartHttpRequest(request), new SmartHttpResponse(response)); + } + }); + + bootstrap.setPort(config.getPort()); + this.bootstrap = bootstrap; + } +} diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/smart/package-info.java b/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/smart/package-info.java new file mode 100644 index 000000000..4c62d9692 --- /dev/null +++ b/hutool-http/src/main/java/org/dromara/hutool/http/server/engine/smart/package-info.java @@ -0,0 +1,24 @@ +/* + * 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. + */ + +/** + * smart-http-server服务器引擎实现
+ * 见:https://smartboot.tech/smart-http/ + * + * @author Looly + * @since 6.0.0 + */ +package org.dromara.hutool.http.server.engine.smart; 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 index 077c0e02d..6f0065bbf 100644 --- 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 @@ -17,4 +17,5 @@ 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.smart.SmartHttpServerEngine org.dromara.hutool.http.server.engine.sun.SunHttpServerEngine diff --git a/hutool-http/src/test/java/org/dromara/hutool/http/server/engine/SmartHttpServerTest.java b/hutool-http/src/test/java/org/dromara/hutool/http/server/engine/SmartHttpServerTest.java new file mode 100644 index 000000000..83c4ad130 --- /dev/null +++ b/hutool-http/src/test/java/org/dromara/hutool/http/server/engine/SmartHttpServerTest.java @@ -0,0 +1,27 @@ +package org.dromara.hutool.http.server.engine; + +import org.dromara.hutool.core.io.file.FileUtil; +import org.dromara.hutool.core.lang.Console; +import org.dromara.hutool.core.net.ssl.SSLContextUtil; +import org.dromara.hutool.crypto.KeyStoreUtil; +import org.dromara.hutool.http.server.ServerConfig; + +import javax.net.ssl.SSLContext; +import java.security.KeyStore; + +public class SmartHttpServerTest { + public static void main(final String[] args) throws Exception { + final char[] pwd = "123456".toCharArray(); + final KeyStore keyStore = KeyStoreUtil.readJKSKeyStore(FileUtil.file("d:/test/keystore.jks"), pwd); + // 初始化SSLContext + final SSLContext sslContext = SSLContextUtil.createSSLContext(keyStore, pwd); + + final ServerEngine engine = ServerEngineFactory.createEngine("SmartHttpServer"); + engine.init(ServerConfig.of().setSslContext(sslContext)); + engine.setHandler((request, response) -> { + Console.log(request.getPath()); + response.write("Hutool Smart-Http response test"); + }); + engine.start(); + } +}