[英]Jsoup http logging
有没有办法记录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 utils 启用日志记录
-Djavax.net.debug=all
由于Jsoup
缺少日志记录(我使用的版本: 1.12.1
)并且使用-Djavax.net.debug=all
JVM 参数日志过于冗长,我发现最好的方法是装饰HttpConnection
类,因此可以自定义什么已记录。 为了实现这一点, execute
方法调用需要通过记录Connection.Request
和Connection.Response
的属性来包围。
使用SLF4J
示例实现:
import org.jsoup.Connection;
import org.jsoup.helper.HttpConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
public class DiagnosticConnection extends HttpConnection {
static final Logger LOG = LoggerFactory.getLogger(DiagnosticConnection.class);
@Override
public Connection.Response execute() throws IOException {
log(this.request());
Connection.Response response = super.execute();
log(response);
return response;
}
public static Connection connect(String url) {
Connection connection = new DiagnosticConnection();
connection.url(url);
return connection;
}
private static void log(Connection.Request request) {
LOG.info("========================================");
LOG.info("[url] {}", request.url());
LOG.info("== REQUEST ==");
logBase(request);
LOG.info("[method] {}", request.method());
LOG.info("[data] {}", request.data());
LOG.info("[request body] {}", request.requestBody());
}
private static void log(Connection.Response response) {
LOG.info("== RESPONSE ==");
logBase(response);
LOG.info("[code] {}", response.statusCode());
LOG.info("[status msg] {}", response.statusMessage());
LOG.info("[body] {}", response.body());
LOG.info("========================================");
}
private static void logBase(Connection.Base<?> base) {
LOG.info("[headers] {}", base.headers());
LOG.info("[cookies] {}", base.cookies());
}
}
使用装饰器时,您应该使用DiagnosticConnection.connect(<URL>)
而不是Jsoup.connect(<URL>)
DiagnosticConnection.connect(<URL>)
基于Gergely Toth 的响应,我创建了自己的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 */
}
现在只需使用LoggerHttpConnection
而不是Jsoup
声明您的请求,一切都会正常工作
Connection.Response res = LoggerHttpConnection.connect("LOGIN_URL_HERE")
.data("user", "USER", "pass", "PASS")
.method(Connection.Method.POST)
.execute();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.