我有一个Android应用程序发布到我的sinatra服务。之前我无法读取sinatra服务的参数。但是,在我将内容类型设置为“x-www-form-urlencoded”之后。我能够看到params,但不是我想要的。我在Sinatra服务中得到了这个请求的副词。
{"{\"user\":{\"gender\":\"female\"},\"session_id\":\"7a13fd20-9ad9-45c2-b308-
8f390b4747f8\"}"=> nil, "splat"=>["update_profile.json"], "captures"=>["update_profile.json"]}
这就是我从我的应用程序发出请求的方式。
StringEntity se;
se = new StringEntity(getJsonObjectfromNameValueList(params.get_params(), "user");
se.setContentType("application/x-www-form-urlencoded");
postRequest.setEntity(se);
private JSONObject getJsonObjectfromNameValueList(ArrayList<NameValuePair> _params, String RootName) {
JSONObject rootjsonObject = new JSONObject();
JSONObject jsonObject = new JSONObject();
if (_params != null) {
if (!_params.isEmpty()) {
for (NameValuePair p : _params) {
try {
if (p.getName().equals(ApplicationFacade.SESSION_ID))
rootjsonObject.put((String) p.getName(), (String) p.getValue());
else
jsonObject.put((String) p.getName(), (String) p.getValue());
} catch (JSONException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
}
}
try {
rootjsonObject.put(RootName, jsonObject);
} catch (JSONException e) {
e.printStackTrace();
}
return rootjsonObject;
}
我尝试使用以下方法:How to make a nested Json object in Java?
这是我使用链接中提到的方法提出请求的方式。
public ArrayList<NameValuePair> getJsonObjectfromNameValueList(ArrayList<NameValuePair> _params, String RootName){
ArrayList<NameValuePair> arrayList = new ArrayList<NameValuePair>();
JSONObject jsonObject = new JSONObject();
if (_params != null) {
if (!_params.isEmpty()) {
for (NameValuePair p : _params) {
try {
if (p.getName().equals(ApplicationFacade.SESSION_ID))
arrayList.add(new BasicNameValuePair((String) p.getName(), (String) p.getValue()));
else
jsonObject.put((String) p.getName(), (String) p.getValue());
} catch (JSONException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
}
}
arrayList.add(new BasicNameValuePair(RootName, jsonObject.toString()));
return arrayList;
}
我做出上述改变后得到的回应是:
{"session_id"=>"958c7dee-f12c-49ec-ab0c-932e9a4ed173",
"user"=>"[gender=male]",
"splat"=>["update_profile.json"],
"captures"=>["update_profile.json"]}
非常接近,但“性别=男性”是不可取的。我需要盲目地将这些参数传递给另一个服务,所以我需要让它们正确。
我在Sinatra服务中想要的参数正在跟随。
{"session_id" : "958c7dee-f12c-49ec-ab0c-932e9a4ed173",
"user":
{
"gender" : "male"
}
}
答案 0 :(得分:6)
事实证明,问题在于Sinatra获得其参数的方式。 我能够使用Kyle对这篇文章的精彩回答来解决我的问题:Sinatra controller params method coming in empty on JSON post request
代码:
before do
if request.request_method == "POST" and request.content_type=="application/json"
body_parameters = request.body.read
parsed = body_parameters && body_parameters.length >= 2 ? JSON.parse(body_parameters) : nil
params.merge!(parsed)
end
end
替代方法:
但是,我找到了一个更好的解决方案来处理它,通过添加一个中间件来为我做同样的事情。我使用了rack-contrib
gem。
以下是我在代码中所做的更改:
编辑:
使用git获取与内容类型application/json;charset=UTF-8
相关的问题已修复的版本
<强>的Gemfile:强>
gem 'rack-contrib', git: 'git@github.com:rack/rack-contrib', ref: 'b7237381e412852435d87100a37add67b2cfbb63'
<强> config.ru 强>:
use Rack::PostBodyContentTypeParser
来源:http://jaywiggins.com/2010/03/using-rack-middleware-to-parse-json/
答案 1 :(得分:1)
使用以下功能对我来说效果更好。我不得不添加request.body.rewind和:symbolize_names =&gt; true(在调用JSON.parse时)
before do
if request.request_method == "POST" and (request.content_type || '').include? "application/json"
request.body.rewind
body_parameters = request.body.read
parsed = body_parameters && body_parameters.length >= 2 ? JSON.parse(body_parameters, :symbolize_names => true) : nil
params.merge!(parsed)
end
end