1

sinatraサービスにAndroidアプリを投稿しています。以前は、sinatraサービスのパラメーターを読み取ることができませんでした。ただし、コンテンツタイプを「x-www-form-urlencoded」に設定した後。私はパラメータを見ることができましたが、私が望んでいた方法ではありませんでした。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;
}

次のメソッドを使用してみました:JavaでネストされたJsonオブジェクトを作成するにはどうすればよいですか?

これが、リンクに記載されている方法を使用してリクエストを行った方法です。

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"
 }

}

4

2 に答える 2

6

問題は、シナトラがパラメーターを取得する方法にあることがわかりました。この投稿に対するKyleの素晴らしい応答を使用して問題を解決することができました:JSON投稿リクエストでSinatraコントローラーのparamsメソッドが空になります

コード:

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: 'git@github.com:rack/rack-contrib', ref: 'b7237381e412852435d87100a37add67b2cfbb63'

config.ru

use Rack::PostBodyContentTypeParser

ソース: http: //jaywiggins.com/2010/03/using-rack-middleware-to-parse-json/

于 2012-09-02T08:14:17.023 に答える
1

以下を使用すると、私にとってはるかにうまくいきました。request.body.rewindと:symbolize_names => 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
于 2014-01-29T20:49:05.887 に答える