add filter

This commit is contained in:
Looly 2021-01-07 21:06:05 +08:00
parent c9a180abce
commit 0a768ad2c6
7 changed files with 165 additions and 11 deletions

View File

@ -14,12 +14,12 @@
* 【setting】 新增setByGroup和putByGroupset和put标记为过期issue#I2C42H@Gitee
* 【crypto 】 修改SymmetricAlgorithm注释issue#1360@Github
* 【all 】 pom中将META-INF/maven下全部excludepr#1355@Github
* 【core 】 pom中将META-INF/maven下全部excludepr#1355@Github
* 【http 】 SimpleServer中增加addFilter等方法并使用全局线程池
### Bug修复
* 【core 】 修复CsvReader读取双引号未转义问题issur#I2BMP1@Gitee
* 【json 】 JSONUtil.parse修复config无效问题issur#1363@Github
* 【http 】 修复SimpleServer返回响应内容Content-Lenth不正确的问题issur#1358@Github
* 【core 】 修复CsvReader读取双引号未转义问题issue#I2BMP1@Gitee
* 【json 】 JSONUtil.parse修复config无效问题issue#1363@Github
* 【http 】 修复SimpleServer返回响应内容Content-Length不正确的问题issue#1358@Github
-------------------------------------------------------------------------------------------------------------

View File

@ -1,6 +1,7 @@
package cn.hutool.http.server;
import cn.hutool.core.util.CharsetUtil;
import com.sun.net.httpserver.HttpContext;
import com.sun.net.httpserver.HttpExchange;
import java.nio.charset.Charset;
@ -34,4 +35,14 @@ public class HttpServerBase {
public HttpExchange getHttpExchange() {
return this.httpExchange;
}
/**
* 获取{@link HttpContext}
*
* @return {@link HttpContext}
* @since 5.5.7
*/
public HttpContext getHttpContext() {
return getHttpExchange().getHttpContext();
}
}

View File

@ -6,13 +6,22 @@ import cn.hutool.core.thread.GlobalThreadPool;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.server.action.Action;
import cn.hutool.http.server.action.RootAction;
import cn.hutool.http.server.filter.HttpFilter;
import cn.hutool.http.server.filter.SimpleFilter;
import cn.hutool.http.server.handler.ActionHandler;
import com.sun.net.httpserver.Filter;
import com.sun.net.httpserver.HttpContext;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpsConfigurator;
import com.sun.net.httpserver.HttpsServer;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
/**
@ -23,7 +32,8 @@ import java.util.concurrent.Executor;
*/
public class SimpleServer {
HttpServer server;
private final HttpServer server;
private final List<Filter> filters;
/**
* 构造
@ -50,26 +60,105 @@ public class SimpleServer {
* @param address 监听地址
*/
public SimpleServer(InetSocketAddress address) {
this(address, null);
}
/**
* 构造
*
* @param address 监听地址
* @param configurator https配置信息用于使用自定义SSLTLS证书等
*/
public SimpleServer(InetSocketAddress address, HttpsConfigurator configurator) {
try {
this.server = HttpServer.create(address, 0);
if(null != configurator){
final HttpsServer server = HttpsServer.create(address, 0);
server.setHttpsConfigurator(configurator);
this.server = server;
} else{
this.server = HttpServer.create(address, 0);
}
} catch (IOException e) {
throw new IORuntimeException(e);
}
setExecutor(GlobalThreadPool.getExecutor());
filters = new ArrayList<>();
}
/**
* 增加请求过滤器此过滤器对所有请求有效<br>
* 此方法需在以下方法前之前调用
*
* <ul>
* <li>{@link #setRoot(File)} </li>
* <li>{@link #setRoot(String)} </li>
* <li>{@link #createContext(String, HttpHandler)} </li>
* <li>{@link #addHandler(String, HttpHandler)}</li>
* <li>{@link #addAction(String, Action)} </li>
* </ul>
*
* @param filter {@link Filter} 请求过滤器
* @return this
* @since 5.5.7
*/
public SimpleServer addFilter(Filter filter) {
this.filters.add(filter);
return this;
}
/**
* 增加请求过滤器此过滤器对所有请求有效<br>
* 此方法需在以下方法前之前调用
*
* <ul>
* <li>{@link #setRoot(File)} </li>
* <li>{@link #setRoot(String)} </li>
* <li>{@link #createContext(String, HttpHandler)} </li>
* <li>{@link #addHandler(String, HttpHandler)}</li>
* <li>{@link #addAction(String, Action)} </li>
* </ul>
*
* @param filter {@link Filter} 请求过滤器
* @return this
* @since 5.5.7
*/
public SimpleServer addFilter(HttpFilter filter) {
return addFilter(new SimpleFilter() {
@Override
public void doFilter(HttpExchange httpExchange, Chain chain) throws IOException {
filter.doFilter(new HttpServerRequest(httpExchange), new HttpServerResponse(httpExchange), chain);
}
});
}
/**
* 增加请求处理规则
*
* @param path 路径
* @param handler 处理器
* @param path 路径例如:/a/b 或者 a/b
* @param handler 处理器包括请求和响应处理
* @return this
* @see #createContext(String, HttpHandler)
*/
public SimpleServer addHandler(String path, HttpHandler handler) {
createContext(path, handler);
return this;
}
/**
* 创建请求映射上下文创建后用户访问指定路径可使用{@link HttpHandler} 中的规则进行处理
*
* @param path 路径例如:/a/b 或者 a/b
* @param handler 处理器包括请求和响应处理
* @return {@link HttpContext}
* @since 5.5.7
*/
public HttpContext createContext(String path, HttpHandler handler) {
// /开头的路径会报错
path = StrUtil.addPrefixIfNot(path, StrUtil.SLASH);
this.server.createContext(path, handler);
return this;
final HttpContext context = this.server.createContext(path, handler);
// 增加整体过滤器
context.getFilters().addAll(this.filters);
return context;
}
/**

View File

@ -0,0 +1,26 @@
package cn.hutool.http.server.filter;
import cn.hutool.http.server.HttpServerRequest;
import cn.hutool.http.server.HttpServerResponse;
import com.sun.net.httpserver.Filter;
import java.io.IOException;
/**
* 过滤器接口用于简化{@link Filter} 使用
*
* @author looly
* @since 5.5.7
*/
@FunctionalInterface
public interface HttpFilter {
/**
* 执行过滤
* @param req {@link HttpServerRequest} 请求对象用于获取请求内容
* @param res {@link HttpServerResponse} 响应对象用于写出内容
* @param chain {@link Filter.Chain}
* @throws IOException IO异常
*/
void doFilter(HttpServerRequest req, HttpServerResponse res, Filter.Chain chain) throws IOException;
}

View File

@ -0,0 +1,17 @@
package cn.hutool.http.server.filter;
import com.sun.net.httpserver.Filter;
/**
* 匿名简单过滤器跳过了描述
*
* @author looly
* @since 5.5.7
*/
public abstract class SimpleFilter extends Filter {
@Override
public String description() {
return "Anonymous Filter";
}
}

View File

@ -0,0 +1,4 @@
/**
* {@link com.sun.net.httpserver.Filter} 实现包装
*/
package cn.hutool.http.server.filter;

View File

@ -11,6 +11,10 @@ public class SimpleServerTest {
public static void main(String[] args) {
HttpUtil.createServer(8888)
.addFilter(((req, res, chain) -> {
Console.log("Filter: " + req.getPath());
chain.doFilter(req.getHttpExchange());
}))
// 设置默认根目录classpath/html
.setRoot(FileUtil.file("html"))
// get数据测试返回请求的PATH
@ -46,7 +50,10 @@ public class SimpleServerTest {
}
)
// 测试输出响应内容是否能正常返回Content-Length头信息
.addAction("test/zeroStr", (req, res)-> res.write("0"))
.addAction("test/zeroStr", (req, res)-> {
res.write("0");
Console.log("Write 0 OK");
})
.start();
}
}