修复SimpleServer在添加的HttpFilter中有获取请求参数时报错问题

This commit is contained in:
Looly 2023-10-25 00:21:20 +08:00
parent 8aef8b36b9
commit 47c07d94ad
4 changed files with 219 additions and 5 deletions

View File

@ -0,0 +1,158 @@
/*
* Copyright (c) 2023. looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* https://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.http.server;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpContext;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpPrincipal;
import org.dromara.hutool.core.func.Wrapper;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.URI;
/**
* {@link HttpExchange}包装类提供增强方法和缓存
*
* @author looly
*/
public class HttpExchangeWrapper extends HttpExchange implements Wrapper<HttpExchange> {
private final HttpExchange raw;
private final HttpServerRequest request;
private final HttpServerResponse response;
/**
* 构造
*
* @param raw {@link HttpExchange}
*/
public HttpExchangeWrapper(final HttpExchange raw) {
this.raw = raw;
this.request = new HttpServerRequest(this);
this.response = new HttpServerResponse(this);
}
@Override
public HttpExchange getRaw() {
return this.raw;
}
/**
* 获取请求
*
* @return 请求
*/
public HttpServerRequest getRequest() {
return request;
}
/**
* 获取响应
*
* @return 响应
*/
public HttpServerResponse getResponse() {
return response;
}
// region ----- HttpExchange methods
@Override
public Headers getRequestHeaders() {
return this.raw.getRequestHeaders();
}
@Override
public Headers getResponseHeaders() {
return this.raw.getResponseHeaders();
}
@Override
public URI getRequestURI() {
return this.raw.getRequestURI();
}
@Override
public String getRequestMethod() {
return this.raw.getRequestMethod();
}
@Override
public HttpContext getHttpContext() {
return this.raw.getHttpContext();
}
@Override
public void close() {
this.raw.close();
}
@Override
public InputStream getRequestBody() {
return this.raw.getRequestBody();
}
@Override
public OutputStream getResponseBody() {
return this.raw.getResponseBody();
}
@Override
public void sendResponseHeaders(final int rCode, final long responseLength) throws IOException {
this.raw.sendResponseHeaders(rCode, responseLength);
}
@Override
public InetSocketAddress getRemoteAddress() {
return this.raw.getRemoteAddress();
}
@Override
public int getResponseCode() {
return this.raw.getResponseCode();
}
@Override
public InetSocketAddress getLocalAddress() {
return this.raw.getLocalAddress();
}
@Override
public String getProtocol() {
return this.raw.getProtocol();
}
@Override
public Object getAttribute(final String name) {
return this.raw.getAttribute(name);
}
@Override
public void setAttribute(final String name, final Object value) {
this.raw.setAttribute(name, value);
}
@Override
public void setStreams(final InputStream i, final OutputStream o) {
this.raw.setStreams(i, o);
}
@Override
public HttpPrincipal getPrincipal() {
return this.raw.getPrincipal();
}
// endregion
}

View File

@ -132,7 +132,8 @@ public class SimpleServer {
return addFilter(new SimpleFilter() {
@Override
public void doFilter(final HttpExchange httpExchange, final Chain chain) throws IOException {
filter.doFilter(new HttpServerRequest(httpExchange), new HttpServerResponse(httpExchange), chain);
final HttpExchangeWrapper httpExchangeWrapper = new HttpExchangeWrapper(httpExchange);
filter.doFilter(httpExchangeWrapper.getRequest(), httpExchangeWrapper.getResponse(), chain);
}
});
}

View File

@ -12,6 +12,7 @@
package org.dromara.hutool.http.server.handler;
import org.dromara.hutool.http.server.HttpExchangeWrapper;
import org.dromara.hutool.http.server.HttpServerRequest;
import org.dromara.hutool.http.server.HttpServerResponse;
import org.dromara.hutool.http.server.action.Action;
@ -41,10 +42,18 @@ public class ActionHandler implements HttpHandler {
@Override
public void handle(final HttpExchange httpExchange) throws IOException {
action.doAction(
new HttpServerRequest(httpExchange),
new HttpServerResponse(httpExchange)
);
final HttpServerRequest request;
final HttpServerResponse response;
if (httpExchange instanceof HttpExchangeWrapper) {
// issue#3343 当使用Filter时可能读取了请求参数此时使用共享的req和res可复用缓存
final HttpExchangeWrapper wrapper = (HttpExchangeWrapper) httpExchange;
request = wrapper.getRequest();
response = wrapper.getResponse();
} else {
request = new HttpServerRequest(httpExchange);
response = new HttpServerResponse(httpExchange);
}
action.doAction(request, response);
httpExchange.close();
}
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2023. looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* https://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.http.server;
import org.dromara.hutool.core.date.DateUtil;
import org.dromara.hutool.core.lang.Console;
import org.dromara.hutool.core.map.multi.ListValueMap;
import org.dromara.hutool.http.HttpUtil;
/**
* http://localhost:8888/?name=hutool
*/
public class Issue3343Test {
public static void main(final String[] args) {
final SimpleServer server = HttpUtil.createServer(8888)
.addFilter((req, res, chain)->{
Console.log(DateUtil.now() + " got request: " + req.getPath());
Console.log(" > from : " + req.getClientIP());
// 过滤器中获取请求参数
Console.log(" > params : " + req.getParams());
chain.doFilter(req.getHttpExchange());
});
server.addAction("/", Issue3343Test::index);
server.start();
}
private static void index(HttpServerRequest request, HttpServerResponse response) {
// 具体逻辑中再次获取请求参数
ListValueMap<String, String> params = request.getParams();
Console.log("index params: " + params);
response.getWriter().write("GOT: " + params);
}
}