注意: 以下のコード/情報を使用すると、この問題を 2 ~ 3 分で再現できます。
背景: まず、Paypal Advanced Interface ("Standard" と "Pro" の間の中間レベルのソリューション) を支援するプラグインが見つかりませんでしたが、独自の HTTPBuilder と他のインターフェイス コードを展開する必要がない場合私は間違いなくそのためです。
これで、HTTPBuilder の問題を絞り込んで、正しい URL を使用して DOS プロンプトから curl コマンドを機能させることができました。GroovyのHTTPBuilderで動作させることができません。
したがって、簡単に試すことができるのは次のとおりです。
c:\groovy\ex>curl https://pilot-payflowpro.paypal.com
curl: (52) Empty reply from server
でもまた返事。または、PayPal から SECURETOKEN を取得するための実際の URL は次のようになります。
c:\groovy\ex>curl https://pilot-payflowpro.paypal.com -kd "PARTNER=PayPal&VENDOR=ROAdvanced&USER=ROAdvanced&PWD=joespizza1&TRXTYPE=S&MODE=TEST&AMT=40&CREATESECURETOKEN=Y&SECURETOKENID=12528208de1413abc3d60c86233"
RESULT=0&SECURETOKEN=15XTWEZtFlkeNqtWCBZHSTgcs&SECURETOKENID=12528208de1413abc3d60c86233&RESPMSG=Approved
OR you'll get a result like the following, but either result is good, since Paypal is sending a response in both cases!
RESULT=7&SECURETOKENID=12528208de1413abc3d60c86233&RESPMSG=Field format error: Secure Token Id already been used
わかりました、私のコードは次のとおりです。遅延を使用しているにもかかわらず(私は思う)、コードがすぐに失敗してエラーになることに注意してください:
Class: org.apache.http.NoHttpResponseException
Message: The target server failed to respond
これは
http.request(GET, ContentType.ANY) {
HTTPBuilder で遅延を設定しても、この失敗はすぐに発生することに注意してください。コード/スタック トレース全体を最後に挿入します。また、この投稿で説明されているようにSSL セキュリティを追加すると、結果は同じエラーになります。つまり、サーバーが応答しませんでした。
したがって、コードは次のとおりです。
package apps
import grails.converters.*
import org.codehaus.groovy.grails.web.json.*; // package containing JSONObject, JSONArray,...
import groovyx.net.http.*
import static groovyx.net.http.ContentType.*
import static groovyx.net.http.Method.*
import javax.net.ssl.X509TrustManager
import javax.net.ssl.SSLContext
import java.security.cert.X509Certificate
import javax.net.ssl.TrustManager
import java.security.SecureRandom
import org.apache.http.conn.ssl.SSLSocketFactory
import org.apache.http.conn.scheme.Scheme
import org.apache.http.conn.scheme.SchemeRegistry
import org.apache.http.conn.ssl.X509HostnameVerifier
class PaypalController {
def index() {
def paypalUrl = "https://pilot-payflowpro.paypal.com?PARTNER=PayPal&VENDOR=ROAdvanced&USER=ROAdvanced&PWD=joespizza1&TRXTYPE=S&MODE=TEST&AMT=40&CREATESECURETOKEN=Y&SECURETOKENID=12528208de1413abc3d60c86cdr87"
//def paypalUrl = "https://pilot-payflowpro.paypal.com"
println "Making new http Builder with paypalURL ..."
def http = new HTTPBuilder(paypalUrl)
println "Now setting timeouts ..."
http.getClient().getParams().setParameter("http.connection.timeout", new Integer(12000))
http.getClient().getParams().setParameter("http.socket.timeout", new Integer(30000))
//=== SSL UNSECURE CERTIFICATE ===
println "Don't know if needed, but since timeouts don't work to get a response, setting up SSL bypass"
def sslContext = SSLContext.getInstance("SSL")
sslContext.init(null, [new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {null }
public void checkClientTrusted(X509Certificate[] certs, String authType) { }
public void checkServerTrusted(X509Certificate[] certs, String authType) { }
}] as TrustManager[], new SecureRandom())
//SSLSocketFactory sf = new org.apache.http.conn.ssl.SSLSocketFactory(sslContext, org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
SSLSocketFactory sf = new org.apache.http.conn.ssl.SSLSocketFactory(sslContext)
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
def httpsScheme = new Scheme("https", sf, 443)
http.client.connectionManager.schemeRegistry.register(httpsScheme)
println "Now doing the get"
// perform a GET request, expecting JSON response data
try {
http.request(GET, ContentType.ANY) {
println "Issued the get waiting for the response"
// Sleeping doesn't help
//Thread.sleep(2000)
// println "Done sleeping, looking to process success"
response.success = { resp, any ->
println "in success code"
println "My response handler got response: ${resp.statusLine}"
println "Response length: ${resp.headers.'Content-Length'}"
assert resp.status == 200
def result = any.results;
render(view: "index", model: [message: "Request sent", result: result]);
}
println "past the success code"
}//end of request
} catch (groovyx.net.http.HttpResponseException ex) {
println "Had response exception ...."
ex.printStackTrace()
return null
} catch (java.net.ConnectException ex) {
println "Had connection exception ...."
ex.printStackTrace()
return null
}
finally {
http.shutdown()
}
}//end of method
def fail() {}
def success() {}
}
------------------- このコードを実行すると (どこにも遅延はありません) -------------------- -----
Making new http Builder with paypalURL ...
Now setting timeouts ...
Don't know if needed, but since timeouts don't work to get a response, setting up SSL bypass
Now doing the get
Issued the get waiting for the response
past the success code
| Error 2013-07-19 13:27:32,301 [http-bio-8080-exec-10] ERROR errors.GrailsExceptionResolver - NoHttpResponseException occurred when processing request: [GET] /apps/paypal/index
The target server failed to respond. Stacktrace follows:
Message: The target server failed to respond
Line | Method
->> 101 | parseHead in org.apache.http.impl.conn.DefaultResponseParser
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 210 | parse in org.apache.http.impl.io.AbstractMessageParser
| 271 | receiveResponseHeader in org.apache.http.impl.AbstractHttpClientConnection
| 233 | receiveResponseHeader in org.apache.http.impl.conn.DefaultClientConnection
| 209 | receiveResponseHeader in org.apache.http.impl.conn.AbstractClientConnAdapter
| 292 | doReceiveResponse in org.apache.http.protocol.HttpRequestExecutor
| 126 | execute . . . . . . . in ''
| 483 | execute in org.apache.http.impl.client.DefaultRequestDirector
| 641 | execute . . . . . . . in org.apache.http.impl.client.AbstractHttpClient
| 576 | execute in ''
| 477 | doRequest . . . . . . in groovyx.net.http.HTTPBuilder
| 441 | doRequest in ''
| 390 | request . . . . . . . in ''
| 56 | index in apps.PaypalController$$EOC4TiIi
| 195 | doFilter . . . . . . in grails.plugin.cache.web.filter.PageFragmentCachingFilter
| 63 | doFilter in grails.plugin.cache.web.filter.AbstractFilter
| 886 | runTask . . . . . . . in java.util.concurrent.ThreadPoolExecutor$Worker
| 908 | run in ''
^ 619 | run . . . . . . . . . in java.lang.Thread
----------------- これを機能させるには、 BuildConfig.groovy に以下を追加する必要がありました ----
...
dependencies {
// specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes e.g.
compile('org.codehaus.groovy.modules.http-builder:http-builder:0.5.2') {
excludes "commons-logging", "xml-apis", "groovy"
}
---------------------------- Ralf の応答によるコードの更新 -------------
うまくいけばGroovy HTTPBuilderのドキュメントと一致するコード:
これにより、同じ行で同じエラーが発生することに注意してください。IE:
org.apache.http.NoHttpResponseException, Message: The target server failed to respond
行: http.request(POST) {
class PaypalController {
def index() {
def paypalUrl = "https://pilot-payflowpro.paypal.com?PARTNER=PayPal&VENDOR=ROAdvanced&USER=ROAdvanced&PWD=joespizza1&TRXTYPE=S&MODE=TEST&AMT=40&CREATESECURETOKEN=Y&SECURETOKENID=12528208de1413abc3d60c86cdr87"
println "Making new http Builder with paypalURL ..."
def http = new HTTPBuilder(paypalUrl)
println "Now doing the post as a request per example"
// perform a GET request, expecting JSON response data
try {
http.request(POST) {
body = [ status : 'update!' , source : 'httpbuilder' ]
requestContentType = ContentType.URLENC
println "Issued the post waiting for the response"
response.success = { resp ->
println "in success code"
println "My response handler got response: ${resp.statusLine}"
println "Response length: ${resp.headers.'Content-Length'}"
assert resp.status == 200
//def result = any.results;
render(view: "index", model: [message: "Request sent", result: result]);
}
println "past the success code"
}//end of request
} catch (groovyx.net.http.HttpResponseException ex) {
println "Had response exception ...."
ex.printStackTrace()
return null
} catch (java.net.ConnectException ex) {
println "Had connection exception ...."
ex.printStackTrace()
return null
}
finally {
http.shutdown()
}
}//end of method
def fail() {}
def success() {}
}