Grails RestBuilder 简单的 POST 示例

Posted

技术标签:

【中文标题】Grails RestBuilder 简单的 POST 示例【英文标题】:Grails RestBuilder simple POST example 【发布时间】: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 【参考方案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

【讨论】:

以上是关于Grails RestBuilder 简单的 POST 示例的主要内容,如果未能解决你的问题,请参考以下文章

grails spring security rest /api/login 401 Unauthorized

Grails:Spring Security 插件对于简单的安全性来说是不是过于强大

简单 grails 控制器单元测试中的空指针

PO模式在Selenium中简单实践

Grails - 简单的 hasMany 问题 - 在 create.gsp 中使用 CheckBoxes 而不是 HTML Select

在 Grails 中使用 HTTP 状态代码呈现 JSON 的简单方法