【问题标题】:Grails RestBuilder simple POST exampleGrails RestBuilder 简单的 POST 示例
【发布时间】:2014-03-11 17:46:51
【问题描述】:

我正在尝试使用 Grails RestBuilder 插件将 OAuth2 用户凭据发布到 OAuth2 服务。

如果我尝试将帖子正文指定为地图,则会收到关于 LinkedHashMap 没有消息转换器的错误。

如果我尝试将正文指定为字符串,则帖子会通过,但不会将任何变量发布到服务器操作。

这是帖子:

RestBuilder rest = new RestBuilder()
def resp = rest.post("http://${hostname}/oauth/token") {
    auth(clientId, clientSecret)
    accept("application/json")
    contentType("application/x-www-form-urlencoded")

    // This results in a message converter error because it doesn't know how
    // to convert a LinkedHashmap
    // ["grant_type": "password", "username": username, "password": password]

    // This sends the request, but username and password are null on the host
    body = ("grant_type=password&username=${username}&password=${password}" as String)
}
def json = resp.json

我也尝试在 post() 方法调用中设置 urlVariables,但用户名/密码仍然为空。

这是一个非常简单的帖子,但我似乎无法让它工作。任何建议将不胜感激。

【问题讨论】:

  • 你可以尝试发送 JSON 而不是 Map 吗? body(["grant_type": "password", "username": username, "password": password] as JSON)。理想情况下,如果内容类型是 JSON,那么您可以直接在 POST 中将正文发送为json {},而不是使用body
  • 我可能可以,但规范指定它应该是 url-formencoded:tools.ietf.org/html/rfc6749#section-4.3.2

标签: rest grails post


【解决方案1】:

我通过对身体使用多值映射解决了这个问题。

RestBuilder rest = new RestBuilder()
MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>()
form.add("grant_type", "password")
form.add("username", username)
form.add("password", password)
def resp = rest.post("http://${hostname}/oauth/token") {
    auth(clientId, clientSecret)
    accept("application/json")
    contentType("application/x-www-form-urlencoded")
    body(form)
}
def json = resp.json

【讨论】:

  • 正确,但在我的情况下,我需要发布 json 描述并上传文件,因此还需要一段代码来将带有 def filebytescont = new File(filename).bytes; ByteArrayResource contentsAsResource = new ByteArrayResource(filebytescont){ String filename = "fileattached"; @Override public String getFilename(){ return filename; } }; 的文件和地图 @ 保留在内存中987654323@ 并且出现内容不同:contentType("application/form-data")
  • 查看 RequestCustomizer 类,它在内部用作 auth()、accept()、contentType() 和 body() 方法的委托。它还有一个 setProperty() 方法,可以将属性添加到 MVM 映射中,因此它基本上可以完成您在 post() 调用之前所做的事情。
【解决方案2】:

以下代码适用于 Box 连接。花几个小时弄清楚这一点

    String pclient_id = grailsApplication.config.ellucian.box.CLIENT_ID.toString()
    String pclient_secret=grailsApplication.config.ellucian.box.CLIENT_SECRET.toString()
    String pcode = params.code

    log.debug("Retrieving the Box Token using following keys Client ID: ==>"+pclient_id+"<== Secret: ==>"+pclient_secret+"<== Code: ==>"+pcode)
    RestBuilder rest = new RestBuilder()

    MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>()
    form.add("client_id", pclient_id)
    form.add("client_secret", pclient_secret)
    form.add("grant_type", "authorization_code")
    form.add("code", pcode)
    def resp = rest.post("https://app.box.com/api/oauth2/token") {
        accept("application/json")
        contentType("application/x-www-form-urlencoded")
        body(form)
    }

    def js = resp.json.toString()
    println("sss"+js)
    def slurper = new JsonSlurper()
    def result = slurper.parseText(js)
    println("Message:"+result.error)

    render js

【讨论】:

    【解决方案3】:

    我发现了一些非常容易执行这种类型的动作

    //Get
     public static RestResponse getService(String url) {
      RestResponse rResponse = new RestBuilder(proxy:["localhost":8080]).get(Constants.URL+"methodName")
      return rResponse
     }
    
     //POST : Send complete request as a JSONObject
     public static RestResponse postService(String url,def jsonObj) {
       RestResponse rResponse = new RestBuilder(proxy:["localhost":8080]).post(url) {
       contentType "application/json"
       json {  jsonRequest = jsonObj  }
      }
      return rResponse
     }
    
    Method 1 :
    
    def resp = RestUtils.getService(Constants.URL+"methodName")?.json
    render resp as JSON
    
    Method 2 :
    
    JSONObject jsonObject = new JSONObject()
    jsonObject.put("params1", params.paramOne)
    jsonObject.put("params2", params.paramTwo)
    def resp = RestUtils.postService(Constants.URL+"methodName", jsonObject)?.json
    render resp as JSON
    

    【讨论】:

      猜你喜欢
      • 2016-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-23
      • 1970-01-01
      • 2014-09-18
      • 2013-10-13
      • 1970-01-01
      相关资源
      最近更新 更多