java - 如何收集 HTTP 请求
问题描述
我需要根据发件人 IP 是否有效,使用 HTTP 请求的字段填充数据库。例如,如果有人在我的 IP 上发出 GET 请求:
/test/demo.php?name1=value1&name2=value2
我怎样才能收到它,以便我可以处理它并执行以下操作:
- 获取发件人的 ip(并验证它 - 只是用一个列表来面对它 -)
- 识别请求的类型
- 推断字段(value1 和 value2)并将它们保存在变量中
我正在使用 java.net.http 包
解决方案
您无法使用包执行该操作,java.net.http
因为您需要创建一个 http 服务器而不是 http 客户端。为此,您需要HttpServer
在 package 中找到它com.sun.net.httpserver
。
首先是创建一个新的 HttpServer 实例:
final int port = 3000;//You can change with your port number you need
final HttpServer httpServer = HttpServer.create(new InetSocketAddress(port), 0);
System.out.println("Listening port : " + port);
然后,配置一个 http 上下文。第一个参数接受您定义的路由,第二个参数接受 http 处理程序,您可以在其中提取需要存储在数据库中的所有数据。
httpServer.createContext("/test/demo.php", buildHttpHandler());//buildHttpHandler is to create
包含什么功能buildHttpHandler()
?:
每次调用路由时,/test/demo.php
都会调用箭头函数的内容。在这里,我们只尝试创建一个简单的页面 html 并将其提供给 http 客户端。但在响应 http 客户端之前,我们需要提取您需要的所有数据(ip、请求类型和参数)。
return httpExchange -> {
final String html = "<!DOCTYPE html>\n" +
"<html>\n" +
" <head>\n" +
" <title>Page</title>\n" +
" <meta charset='utf-8'/>\n" +
" </head>\n" +
" <body>Ok</body>\n" +
"</html>";
//Function to create
extractData(httpExchange);
httpExchange.getResponseHeaders().set("Content-Type", "text/html; charset=utf-8");
httpExchange.sendResponseHeaders(200, html.length());
final OutputStream outputStream = httpExchange.getResponseBody();
outputStream.write(html.getBytes(StandardCharsets.UTF_8));
outputStream.close();
};
包含什么extractData()
功能?
在此功能中,我们将提取您需要的数据。
final String ip = getClientIp(httpExchange);
System.out.println("IP : " + ip);
final String requestType = httpExchange.getRequestMethod();
System.out.println("Request type : " + requestType);
final Map<String, String> parameters = extractParameters(httpExchange);
displayParameters(parameters);
提取 ip 客户端更加复杂,因为有时客户端使用代理,这就是我们创建专用函数getClientIp()
来提取 ip 的原因。
在这个函数中,我们首先尝试提取代理 ip。如果没有找到,我们从 remote 中提取标准 ip:
final String ip = getProxyIp(httpExchange);
return ip == null ? httpExchange.getRemoteAddress().getAddress().getHostAddress() : ip;
为了提取代理 ip,我们创建了另一个函数getProxyIp()
。它尝试提取从x-forwarded-for
请求标头中提供的 ip。
final List<String> ips = httpExchange.getRequestHeaders().get("x-forwarded-for");
return ips == null ? null : ips.get(ips.size() - 1);
我不知道外推字段是什么意思,但您可以将所有数据存储在 Map 变量中。键将是参数的名称,值将是参数的值。但这也很复杂,因为我们需要从name1=value1&name2=value2
. 所以,我们创建一个新函数extractParameters()
。它包含 :
final String query = httpExchange.getRequestURI().getQuery();
final Map<String, String> parameters = new HashMap<>();
if (query != null) {
final String[] firstParts = query.split("&");
for (final String firstPart : firstParts) {
final String[] secondParts = firstPart.split("=");
final String name = secondParts[0];
final String value = secondParts.length > 1 ? secondParts[1] : null;
parameters.put(name, value);
}
}
return parameters;
你可能注意到什么是displayParameters()
内容。它只是尝试显示从extractParameters()
.
for (final Map.Entry<String, String> parameter : parameters.entrySet()) {
System.out.println("Parameter key : " + parameter.getKey());
System.out.println("Parameter value : " + parameter.getValue());
}
最后别忘了启动 http 服务器:
httpServer.start();
您可以在此处查看完整代码https://gist.github.com/razafinarivohanania/24fe0986ea5868097404f2a758131823
当你测试它时,你可以得到类似的东西:
IP : 127.0.0.1
Request type : GET
Parameter key : name2
Parameter value : value2
Parameter key : name1
Parameter value : value1
推荐阅读
- reactjs - KeyboardDatePickerExample:在 React 中将显示呈现为 moment.local() 时,在 State 中将日期设置为 moment.utc()
- r - R dplyr purr 查找跨多个列的列最小值的索引值和索引处的相应行值
- javascript - 如何仅使用修改的模块/文件发布电子应用程序?
- javascript - 向元素添加多个图像的问题(javascript循环问题)
- java - Java - OAuth 2.0 获取访问令牌
- java - Spring Boot WebFluxTest 测试,无法实例化存储库,指定的类是一个接口
- javascript - 通过javascript提交HTML表单并防止默认
- assembly - NASM 赋值
- c# - Microsoft Graph API 不准确的错误消息
- python - 基本 Python - 通过 input() 将硬编码的 int 变量与动态 int 变量进行比较时,无法使 IF 语句工作