html看报错在哪里查看,htmlunit实现模拟浏览器请求报错sslcontext没有的解决思路...

最近在升级springmvc项目到springboot项目,原来用htmlunit写的模拟百度浏览器查询关键字功能,一直报错,异常信息也比较少:java.lang.NoSuchFieldException: sslcontext。

从信息上来看应该是java反射获取属性的时候找不见。最开始怀疑是因为版本升级引起的。在查看以后,将原来明显相关的三个包查看发现其中一个的版本确实不一致,于是通过dependency依赖直接替换为原版本,发现还不行,报错一直是:java.lang.NoSuchFieldException: sslcontext.

那么我们通过maven的试图看看htmlunit的jar自动引入的依赖是什么。

我们在pom文件中引入:

net.sourceforge.htmlunit

htmlunit

2.14

那么这个依赖做了什么:

bc0fbbdae58acc3b49ab206289aa7088.png

从这个图中可以看出,htmlunit包会默认加载很多他自己的依赖,包括我用蓝框圈住的httpClient,我们之前看到的报错就来自这个包:

根据报错行:

// 百度搜索首页页面

HtmlPage htmlPage = webClient.getPage("https://www.baidu.com/gaoji/advanced.html");

慢慢的跟进去你就可以走到:HttpWebConnection这个类的getResponse方法

public WebResponse getResponse(final WebRequest request) throws IOException {

final URL url = request.getUrl();

final HttpClientBuilder builder = reconfigureHttpClientIfNeeded(getHttpClientBuilder());

HtmlUnitHttpClientBuilder.configureConnectionManager(builder);

HttpUriRequest httpMethod = null;

try {

try {

httpMethod = makeHttpMethod(request);

}

catch (final URISyntaxException e) {

throw new IOException("Unable to create URI from URL: " + url.toExternalForm()

+ " (reason: " + e.getMessage() + ")", e);

}

final HttpHost hostConfiguration = getHostConfiguration(request);

// setProxy(httpMethod, request);

final long startTime = System.currentTimeMillis();

HttpResponse httpResponse = null;

try {

httpResponse = builder.build().execute(hostConfiguration, httpMethod, httpContext_);

}

catch (final SSLPeerUnverifiedException s) {

// Try to use only SSLv3 instead

if (webClient_.getOptions().isUseInsecureSSL()) {

HtmlUnitSSLConnectionSocketFactory.setUseSSL3Only(httpContext_, true);

httpResponse = builder.build().execute(hostConfiguration, httpMethod);

}

else {

throw s;

}

}

catch (final Error e) {

// in case a StackOverflowError occurs while the connection is leased, it won't get released.

// Calling code may catch the StackOverflowError, but due to the leak, the httpClient_ may

// come out of connections and throw a ConnectionPoolTimeoutException.

// => best solution, discard the HttpClient instance.

synchronized (this) {

httpClientBuilder_ = null;

}

throw e;

}

final DownloadedContent downloadedBody = downloadResponseBody(httpResponse);

final long endTime = System.currentTimeMillis();

return makeWebResponse(httpResponse, request, downloadedBody, endTime - startTime);

}

finally {

if (httpMethod != null) {

onResponseGenerated(httpMethod);

}

}

}

重点在这一句:

HtmlUnitHttpClientBuilder.configureConnectionManager(builder);

去构建执行器的时候报错:

02f170d0a5b951c919e2fb9367caefc9.png

我红框标记的地方就是获取sslcontext的地方,而这个builder根据方法参数,我们可以查看到这个

HttpClientBuilder这个类中是否存在属性sslcontext。

d27cdb518d2bd6cf55132af93722dcc4.png

如果你在报sslcontext属性没有,那你对应的类中应该是没有我框出来的这个属性的。这说明你的其他依赖或者当前依赖引入的包中的httpclient包中的HttpClientBuilder这个类对象不兼容。需要做替换,或者用htmlunit包默认引进的,需要把手动引入或因为其他依赖引入的包引起的问题解决掉。

我这里遇到的是4.5.2版本的httpclient里面没有这个属性所以报错,我回退到4.3.2版本,问题解决。

到这里基本上就完成了问题的排查。当然因为这个htmlunit还有其他多个依赖从图中可以看出,如果你项目中有其他的依赖jar和它的jar有相同的依赖,都有可能会引起这种问题。解决思路是相同的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值