Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Jsoup http日志记录_Java_Html_Http_Logging_Jsoup - Fatal编程技术网

Java Jsoup http日志记录

Java Jsoup http日志记录,java,html,http,logging,jsoup,Java,Html,Http,Logging,Jsoup,有没有办法记录http请求和响应? 让我们假设下面的请求 Connection.Response res = Jsoup.connect("LOGIN_URL_HERE") .data("user", "USER", "pass", "PASS") .method(Connection.Method.POST) .execute(); 如何记录http请求和响应?请注意,我想要的是HTTP,而不仅仅是要解析的HTML 默认

有没有办法记录http请求和响应? 让我们假设下面的请求

Connection.Response res = Jsoup.connect("LOGIN_URL_HERE")
            .data("user", "USER", "pass", "PASS")
            .method(Connection.Method.POST)
            .execute();

如何记录http请求和响应?请注意,我想要的是HTTP,而不仅仅是要解析的HTML

默认情况下,jsoup使用
java.net.HttpURLConnection
的实现,因此我认为您需要为该实现打开日志记录(可能是:
sun.net.www.protocol.http.HttpURLConnection)
java.net

有一个系统属性可以为java net UTIL启用日志记录

-Djavax.net.debug=all

由于
Jsoup
缺少日志记录(我正在使用的版本:
1.12.1
),并且使用
-Djavax.net.debug=所有的
JVM参数日志都太冗长,所以我发现最好的方法是修饰
HttpConnection
类,这样就可以自定义记录的内容。要实现这一点,
execute
方法调用需要记录
Connection.Request
Connection.Response
的属性

使用
SLF4J
的示例实现:

import org.jsoup.Connection;
导入org.jsoup.helper.HttpConnection;
导入org.slf4j.Logger;
导入org.slf4j.LoggerFactory;
导入java.io.IOException;
公共类DiagnosticConnection扩展了HttpConnection{
静态最终记录器日志=LoggerFactory.getLogger(DiagnosticConnection.class);
@凌驾
public Connection.Response execute()引发IOException{
日志(this.request());
Connection.Response=super.execute();
日志(响应);
返回响应;
}
公共静态连接(字符串url){
连接=新诊断连接();
url(url);
回路连接;
}
专用静态无效日志(Connection.Request){
日志信息(“============================================================================”);
LOG.info(“[url]{}”,request.url());
LOG.info(“==请求==”);
logBase(请求);
LOG.info(“[method]{}”,request.method());
LOG.info(“[data]{}”,request.data());
LOG.info(“[request body]{}”,request.requestBody());
}
专用静态无效日志(Connection.Response){
LOG.info(“==响应==”);
logBase(响应);
LOG.info(“[code]{}”,response.statusCode());
LOG.info(“[status msg]{}”,response.statusMessage());
LOG.info(“[body]{}”,response.body());
日志信息(“============================================================================”);
}
专用静态void logBase(Connection.Base){
LOG.info(“[headers]{}”,base.headers());
LOG.info(“[cookies]{}”,base.cookies());
}
}
使用decorator时,不应使用
Jsoup.connect()
而应使用
DiagnosticConnection.connect()

基于响应,我已经创建了自己的
LoggerHttpConnection
,我正在使用它

import android.util.Log
import org.jsoup.Connection
import org.jsoup.helper.HttpConnection
import org.jsoup.nodes.Document
import org.jsoup.parser.Parser
import java.io.InputStream
import java.net.Proxy
import java.net.URL
import javax.net.ssl.SSLSocketFactory

class LoggerHttpConnection private constructor(
    private val delegate: HttpConnection,
    private val saveFile: Boolean
) : Connection {

    private val tag = "LoggerHttpConnection"

    companion object {
        fun connect(url: String, saveFile: Boolean = false): LoggerHttpConnection {
            return LoggerHttpConnection(
                HttpConnection.connect(url) as HttpConnection,
                saveFile
            )
        }
    }

    private fun log(request: Connection.Request): String {
        Log.i(tag, "========================================")
        var line = "[url] ${request.url()}"
        var log = "$line\n\n== REQUEST ==\n"
        Log.i(tag, line)

        Log.i(tag, "== REQUEST ==")
        log += logBase(request)

        line = "[method] ${request.method()}"
        log += "$line\n"
        Log.i(tag, line)

        for (data in request.data()) {
            line = "[data] ${data.key()}=${data.value()}"
            log += "$line\n"
            Log.i(tag, line)
        }

        line = "[request body] ${request.requestBody()}"
        log += "$line\n"
        Log.i(tag, line)

        return log
    }

    private fun log(response: Connection.Response): String {
        var line = ""
        var log = "\n== RESPONSE ==\n"

        Log.i(tag, "== RESPONSE ==")
        log += logBase(response)

        line = "[code] ${response.statusCode()}"
        log += "$line\n"
        Log.i(tag, line)

        line = "[status msg] ${response.statusMessage()}"
        log += "$line\n"
        Log.i(tag, line)

        line = "[body] ${response.body()}"
        log += "$line\n"
        Log.i(tag, line)

        Log.i(tag, "========================================")

        return log
    }

    private fun logBase(base: Connection.Base<*>): String {
        var line = ""
        var log = ""
        for (header in base.headers()) {
            line = "[header] ${header.key}=${header.value}"
            log += "$line\n"
            Log.i(tag, line)
        }
        for (cookie in base.cookies()) {
            line = "[cookie] ${cookie.key}: ${cookie.value}"
            log += "$line\n"
            Log.i(tag, line)
        }
        return log
    }

    override fun execute(): Connection.Response {
        var logs = log(request())
        val response = delegate.execute()
        logs += log(response)
        if (saveFile)
            logs.saveToFile("request_log") //do something to save your log in a file if its necesary
        return response
    }

    override fun ignoreContentType(ignoreContentType: Boolean): Connection {
        delegate.ignoreContentType(ignoreContentType)
        return this
    }

    override fun postDataCharset(charset: String?): Connection {
        delegate.postDataCharset(charset)
        return this
    }

    override fun get(): Document {
        return delegate.get()
    }

    override fun post(): Document {
        return delegate.post()
    }

    /** Continue implementing necessary methods for Connection */

}

请看这里:我出错了,因为
HttpConnection
没有公共构造函数。错误:
在“org.jsoup.helper.HttpConnection”中没有可用的默认构造函数。
Connection.Response res = LoggerHttpConnection.connect("LOGIN_URL_HERE")
        .data("user", "USER", "pass", "PASS")
        .method(Connection.Method.POST)
        .execute();