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 - 简单的 hasMany 问题 - 在 create.gsp 中使用 CheckBoxes 而不是 HTML Select