2012-09-01 37 views
0

我有一个android应用发布到我的sinatra服务。之前我无法读取我的sinatra服务的参数。但是,在将内容类型设置为“x-www-form-urlencoded”之后。我能够看到参数,但不是我想要的。我将这件事作为我在sinatra服务中的要求的参数。从java发布JSON参数到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

你可以尝试为application/json的ContentType? – Chris

+0

我已经做了。在我的sinatra服务中看不到参数。尽管我可以使用request.body来阅读它们。阅读,但这似乎是一个解决方法。 – goyalankit

+0

我不明白解释和问题是什么?你用了很多这个词,但我不知道你指的是什么。 – gigadot

回答

5

事实证明,问题与西纳特拉获取其PARAMS的方式。 我能解决使用凯尔的这个帖子真棒回应我的问题: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宝石。 以下是我在我的代码做了修改:

编辑

使用git获得其中的问题涉及到的内容类型的版本application/json;charset=UTF-8是固定的

的Gemfile:

gem 'rack-contrib', git: '[email protected]:rack/rack-contrib', ref: 'b7237381e412852435d87100a37add67b2cfbb63' 

config.ru

use Rack::PostBodyContentTypeParser 

来源:http://jaywiggins.com/2010/03/using-rack-middleware-to-parse-json/

1

使用下面的工作对我来说要好得多。我不得不添加request.body.rewind和:symbolize_names =>真(同时呼吁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