2016-05-14 43 views
1

我不想刮一个网站,这需要我登录。我决定使用Jsoup来做到这一点。我无法“翻译”这一行代码Clojure的正确:指定clojure中的对象类

Connection.Response loginForm = Jsoup.connect("**url**") 
     .method(Connection.Method.GET) 
     .execute(); 

没有在我的Clojure代码指定类Connection.Response,连接有类jsoup.helper.HttpConnect,缺少我需要的Cookie会话方法。

到目前为止,我想出了下面的Clojure代码:

(import (org.jsoup Jsoup Connection 
       Connection$Response Connection$Method)) 
(do 
(def url "*URL*") 
(def res (doto (org.jsoup.Jsoup/connect url) 
    (.data "username" "*USERNAME*") 
    (.data "password" "*PASSWORD") 
    (.method Connection$Method/POST) 
    (.execute))) 
(type res)) 

回答

5

是您正在使用doto,你应该使用一个线程->宏观问题:

(let [url "*URL*"] 
    (-> url 
     (org.jsoup.Jsoup/connect) 
     (.data "username" "*USERNAME*") 
     (.data "password" "*PASSWORD*") 
     (.method "Connection$Method/POST) 
     (.execute))) 

doto形式通常在你需要设置一个Java对象时使用,该对象提供了类似setter的方法,返回void并且阻止你使用线程。

(doto (SomeClass.) 
    (.setA 1) 
    (.setB 2) 
    (.execute)) 

翻译成:

(let [obj (SomeClass.)] 
    (.setA obj 1) 
    (.setB obj 2) 
    (.execute obj) 
    obj) 

正如你可以看到doto不返回的最后一个方法调用,但作为第一个参数提供的对象(SomeClass对象在这种情况下)的结果。因此,您当前的代码将返回由Jsoup/connect方法(jsoup.helper.HttpConnect作为通知)创建的对象,而不是​​方法调用的Connection.Response结果。

你需要的是:

(-> (SomeClass.) 
    (.withA 1) 
    (.withB 2) 
    (.execute)) 

其中with*是生成器方法返回this代替void

上述螺纹形式是等同于:

(.execute 
    (.withB 
    (.withA 
     (SomeClass.) 
     1) 
    2))