我在Grails中編寫了一個REST客戶端,我需要使用OAUTH與第三方CRM進行集成,所以我使用的是HTTP-Builder。我想抽象OAUTH的東西到一個服務,並使令牌和instance_url控制器和視圖可用。如何在Grails中的控制器中調用服務?
這裏是我的服務:
import org.springframework.transaction.annotation.Transactional;
import groovyx.net.http.HTTPBuilder
import groovyx.net.http.HttpResponseException
import static groovyx.net.http.ContentType.URLENC
import static groovyx.net.http.Method.POST
import static groovyx.net.http.Method.GET
import static groovyx.net.http.ContentType.JSON
class APIConnectorService {
def sf_login_domain = 'STUFFTHATWORKS'
def instance_domain
def access_token = ''
def consumer_key = 'STUFFTHATWORKS'
def consumer_secret = 'STUFFTHATWORKS'
def auth_username = 'STUFFTHATWORKS'
def auth_password = 'STUFFTHATWORKS'
def serviceMethod() {
//Request Access_token and instance domain for work
def http = new HTTPBuilder(sf_login_domain)
def postBody = [
grant_type: 'password',
client_id: consumer_key,
client_secret: consumer_secret,
username: auth_username,
password: auth_password+auth_security_token
]
try{
http.post(path : 'services/oauth2/token',
body : postBody,
requestContentType: URLENC) { resp, json ->
access_token = json.access_token
instance_domain = json.instance_url +"/"
}
}catch(HttpResponseException e){
println "Error code: ${e.statusCode}"
println "Post form: $postBody"
}
println "Access Token $access_token"
println "Instance domain $instance_domain \n"
}
}
這是我的位指示
import groovyx.net.http.HTTPBuilder
import groovyx.net.http.HttpResponseException
import static groovyx.net.http.ContentType.URLENC
import static groovyx.net.http.Method.POST
import static groovyx.net.http.Method.GET
import static groovyx.net.http.ContentType.JSON
class APIConnectorController {
def APIConnectorService
def index(){
http = new HTTPBuilder(APIConnectorService.serviceMethod())
http.request(GET,JSON) { req ->
uri.path = 'services/data/v28.0/'
headers['Authorization'] = "Bearer $access_token"
response.success = { resp, json ->
assert resp.status == 200
json.each{ key,value ->
render(view:"index", model: [json: json])
}
}
response.failure = { resp, json ->
println resp.status
println json.errorCode
println json.message
}
}
}
}
所以,當我直接包括在它的表現我很喜歡,但最好的方式控制所有的服務代碼,我說我想抽象的OAUTH令牌生成服務(至少,這是最有意義的)。
我得到這個錯誤,當我嘗試上述配置
ERROR errors.GrailsExceptionResolver - MissingMethodException occurred when processing request: [GET] /SFAPITest/APIConnector
No signature of method: sfapitest.APIConnectorController.HTTPBuilder() is applicable for argument types: (null) values: [null]. Stacktrace follows:
Message: No signature of method: sfapitest.APIConnectorController.HTTPBuilder() is applicable for argument types: (null) values: [null]
更新!
我越來越從服務到控制器通過訪問令牌和實例域,但現在我得到的錯誤:
ERROR errors.GrailsExceptionResolver - MissingMethodException occurred when processing request: [GET] /SFAPITest/ApiConnector
No signature of method: sfapitest.ApiConnectorController.HTTPBuilder() is applicable for argument types: (java.lang.String) values: [https://scholastica--FullBox.cs16.my.salesforce.com/]. Stacktrace follows:
Message: No signature of method: sfapitest.ApiConnectorController.HTTPBuilder() is applicable for argument types: (java.lang.String) values: [https://ourschool--FullBox.cs16.my.forcefulCRM.com/]
這裏是我的更新服務
package sfapitest
import groovyx.net.http.HTTPBuilder
import groovyx.net.http.HttpResponseException
import static groovyx.net.http.ContentType.URLENC
import static groovyx.net.http.Method.POST
import static groovyx.net.http.Method.GET
import static groovyx.net.http.ContentType.JSON
class ApiConnectorService {
def transactional = false
def sf_login_domain = 'STUFFTHATWORKS'
def instance_domain
def access_token = ''
def consumer_key = 'STUFFTHATWORKS'
def consumer_secret = 'STUFFTHATWORKS'
def auth_username = 'STUFFTHATWORKS'
def auth_password = 'STUFFTHATWORKS'
def auth_security_token = 'STUFFTHATWORKS'
def api_token_path = 'services/oauth2/token'
def oauthObject
def serviceMethod() {
//Request Access_token and instance domain for work
def http = new HTTPBuilder(sf_login_domain)
def postBody = [
grant_type: 'password',
client_id: consumer_key,
client_secret: consumer_secret,
username: auth_username,
password: auth_password+auth_security_token
]
try{
http.post(path : api_token_path,
body : postBody,
requestContentType: URLENC) { resp, json ->
access_token = json.access_token
instance_domain = json.instance_url +"/"
}
oauthObject = [access_token, instance_domain]
}catch(HttpResponseException e){
println "Error code: ${e.statusCode}"
println "Post form: $postBody"
}
return oauthObject
}
}
所以感謝以下建議,我將access_token和instance _domain的數組返回給serviceMethod()。
這裏是我的控制器:
package sfapitest
import groovyx.net.http.HTTPBuilder
import groovyx.net.http.HttpResponseException
import static groovyx.net.http.ContentType.URLENC
import static groovyx.net.http.Method.POST
import static groovyx.net.http.Method.GET
import static groovyx.net.http.ContentType.JSON
class ApiConnectorController {
def apiConnectorService
def index(){
def access_token = apiConnectorService.serviceMethod()[0]
def instance_domain = apiConnectorService.serviceMethod()[1]
http = HTTPBuilder(instance_domain)
http.request(GET,JSON) { req ->
uri.path = 'services/data/v28.0/'
headers['Authorization'] = "Bearer $access_token"
response.success = { resp, json ->
assert resp.status == 200
json.each{ key,value ->
render(view:"index", model: [json: json])
}
}
response.failure = { resp, json ->
println resp.status
println json.errorCode
println json.message
}
}
}
}
MissingMethodException可能意味着我沒有正確的參數個數。我可以從cotroller渲染access_token和instance_domain,並顯示正確的值。任何有關如何使這項工作和更優雅的提示和指針將不勝感激。我的目標是製作可用於各種第三方Web服務集成的RESTful/OAuth應用程序。
@Lorenzo,我現在將access_token和instance_domain從服務返回到控制器。謝謝!但是我得到錯誤'沒有方法的簽名:ApiConnectorController.HTTPBuilder()適用於參數類型:(java.lang.String)values:[https://ourschool--FullBox.cs16.my.forcefulCRM.com /]' – Baci