首页 > 解决方案 > 如何收集 HTTP 请求

问题描述

我需要根据发件人 IP 是否有效,使用 HTTP 请求的字段填充数据库。例如,如果有人在我的 IP 上发出 GET 请求:

/test/demo.php?name1=value1&name2=value2 

我怎样才能收到它,以便我可以处理它并执行以下操作:

我正在使用 java.net.http 包

标签: javahttppostgetrequest

解决方案


您无法使用包执行该操作,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

推荐阅读