8

所以我试图从我正在编写的 Android 应用程序发布到 Rails 应用程序。我可以从 Rails 应用程序中成功发布。我还能够使用名为 Simple Rest 客户端的 chrome 插件成功发布。

在此处输入图像描述

当我尝试从 Android 应用程序发布时,它会点击 rails 应用程序,但会创建一个空帖子。rails 没有接收到任何输入数据。

我读到第 3 方应用程序只能根据身份验证从 Rails 应用程序获取,因此为了确保这不是我遇到的问题,我将其添加到我的 Rails 配置中。

# de-activate tolken auth
config.action_controller.allow_forgery_protection = false

在这一点上,我不确定我的问题出在哪里,是我的 Rails 后端还是我的 Android 客户端。

好的,所以我试图达到的控制器中的 Rails post 方法就在这里

# POST /orders
  # POST /orders.json
  def create
    @order = Order.new(params[:order])

    respond_to do |format|
      if @order.save
        format.html { redirect_to @order, notice: 'Order was successfully created.' }
        format.json { render json: @order, status: :created, location: @order }
      else
        format.html { render action: "new" }
        format.json { render json: @order.errors, status: :unprocessable_entity }
      end
    end
  end

这是用于发送 Post 请求的 Android java 代码。这是传递我要发布的用户输入数据的方法

private void postInformationtoAPI() {

                showToast("POSTING ORDER");
                List<NameValuePair> apiParams = new ArrayList<NameValuePair>();
                apiParams.add(new BasicNameValuePair("drinks_id", GlobalDrinkSelected));
                apiParams.add(new BasicNameValuePair("name", GlobalEditTextInputName));
                apiParams.add(new BasicNameValuePair("paid" , GlobalIsPaid));

                bgtPost = new BackGroundTaskPost(MAP_API_URL_POST_ORDER, "POST", apiParams);
                bgtPost.execute();

                goToOrderCompleted();

            }

这就是它传递给的类,用于执行 HTTP POST。

public class BackGroundTaskPost extends AsyncTask<String, String, JSONObject> {

     List<NameValuePair> postparams = new ArrayList<NameValuePair>();
     String URL = null;
     String method = null;

     static InputStream is = null;
     static JSONObject jObj = null;
     static String json = "";

     public BackGroundTaskPost(String url, String method, List<NameValuePair> params) {
      this.URL = url;
      this.postparams = params;
      this.method = method;

      for (int i = 0; i < postparams.size(); i++){
          String test = postparams.get(i).toString();
          Log.d("This is in the lisht:", test);
      }
     }

     @Override
     protected JSONObject doInBackground(String... params) {
      // TODO Auto-generated method stub
      // Making HTTP request
      try {
       // Making HTTP request
       // check for request method

       if (method.equals("POST")) {
        // request method is POST
        // defaultHttpClient

           DefaultHttpClient httpClient = new DefaultHttpClient();
           HttpPost httpPost = new HttpPost(URL);
           httpPost.setEntity(new UrlEncodedFormEntity(postparams, HTTP.UTF_8));
           Log.i("postparams : ", postparams.toString());
           httpPost.setHeader("Content-Type", "application/json");
           httpPost.setHeader("Accept", "application/json");

           HttpResponse httpResponse = httpClient.execute(httpPost);
           HttpEntity httpEntity = httpResponse.getEntity();
           is = httpEntity.getContent();

       } else if (method == "GET") {
        // request method is GET
        DefaultHttpClient httpClient = new DefaultHttpClient();
        String paramString = URLEncodedUtils
          .format(postparams, "utf-8");
        URL += "?" + paramString;
        HttpGet httpGet = new HttpGet(URL);

        HttpResponse httpResponse = httpClient.execute(httpGet);
        HttpEntity httpEntity = httpResponse.getEntity();
        is = httpEntity.getContent();
       }

      } catch (UnsupportedEncodingException e) {
       e.printStackTrace();
      } catch (ClientProtocolException e) {
       e.printStackTrace();
      } catch (IOException e) {
       e.printStackTrace();
      }

      try {
          Log.i("Logging out *is* before beffered reader", is.toString());
       BufferedReader reader = new BufferedReader(new InputStreamReader(
         is, "utf-8"), 8);
       Log.i("Logging out *is* after beffered reader", is.toString());
       StringBuilder sb = new StringBuilder();
       String line = null;
       while ((line = reader.readLine()) != null) {
        sb.append(line + "\n");
       }
       is.close();
       json = sb.toString();
       Log.i("json: ",json);
      } catch (Exception e) {
       Log.e("Buffer Error", "Error converting result " + e.toString());
      }

      // try parse the string to a JSON object
      try {
       jObj = new JSONObject(json);
      } catch (JSONException e) {
       Log.e("JSON Parser", "Error parsing data TEST " + e.toString());
      }

      // return JSON String
      return jObj;

     }
    }

这是上面类中 postparams 的日志,所以我知道实际上正在发送数据

04-03 21:36:23.994: I/postparams :(690): [drinks_id=41, name=Dave, paid=True]

这就是 Log Cat 显示为来自服务器的响应

04-03 20:56:08.247: I/json:(690): {"created_at":"2013-04-03T20:56:06Z","drinks_id":null,"id":1351,"name":null,"paid":null,"served":null,"updated_at":"2013-04-03T20:56:06Z"}

我真的很难理解问题出在哪里,并且已经坚持了很长时间。任何见解将不胜感激。如果需要更多信息,请大声喊叫。

编辑:来自服务器的日志

这是来自简单 REST 客户端的成功帖子

2013-04-03T23:13:31+00:00 app[web.1]: Completed 200 OK in 15ms (Views: 8.7ms | ActiveRecord: 5.2ms)
2013-04-03T23:13:42+00:00 app[web.1]: Started POST "/orders.json" for 89.101.112.167 at 2013-04-03 23:13:42 +0000
2013-04-03T23:13:42+00:00 app[web.1]: Processing by OrdersController#create as JSON
2013-04-03T23:13:42+00:00 app[web.1]:   Parameters: {"updated_at"=>nil, "drinks_id"=>51, "id"=>1021, "name"=>"Test", "paid"=>true, "served"=>nil, "created_at"=>nil, "order"=>{"drinks_id"=>51, "name"=>"Test", "paid"=>true, "served"=>nil}}
2013-04-03T23:13:43+00:00 heroku[router]: at=info method=POST path=/orders.json host=fyp-coffeeshop.herokuapp.com fwd="89.101.112.167" dyno=web.1 connect=1ms service=25ms status=201 bytes=138
2013-04-03T23:13:43+00:00 app[web.1]: Completed 201 Created in 15ms (Views: 0.6ms | ActiveRecord: 13.2ms)

这是来自 android 应用程序发布

2013-04-03T22:56:45+00:00 app[web.1]: Started POST "/orders.json" for 89.101.112.167 at 2013-04-03 22:56:45 +0000
2013-04-03T22:56:45+00:00 app[web.1]: Processing by OrdersController#create as JSON
2013-04-03T22:56:45+00:00 app[web.1]: Completed 201 Created in 23ms (Views: 2.2ms | ActiveRecord: 16.3ms)
2013-04-03T22:56:45+00:00 heroku[router]: at=info method=POST path=/orders.json host=fyp-coffeeshop.herokuapp.com fwd="89.101.112.167" dyno=web.1 connect=4ms service=37ms status=201 bytes=138
4

2 回答 2

6

您正在设置 JSON 的内容类型,但实际上并未发送 JSON,您正在发送标准的 POST url 编码参数。

您需要实际发送一个 JSON 对象:

JSONObject params = new JSONObject();
params.put("drinks_id", GlobalDrinkSelected);
params.put("name", GlobalEditTextInputName);
params.put("paid", GlobalIsPaid);

StringEntity entity = new StringEntity(params.toString());
httpPost.setEntity(entity);
于 2013-04-04T00:08:30.720 回答
1

问题是,当您在 Android 中构建 POST 时,您会覆盖实体(主体)。您最初设置它,然后再次设置它,有效地清除您已经设置的内容。

这是对的:

httpPost.setEntity(new UrlEncodedFormEntity(postparams));

但是几行之后,您将其覆盖为:

httpPost.setEntity(new StringEntity("UTF-8"));

所以放弃第二个setEntity()电话。

您可以实现您想要做的 - 通过调整您的代码以 UTF-8 设置 POST 正文:

httpPost.setEntity(new UrlEncodedFormEntity(postparams, HTTP.UTF_8));
于 2013-04-03T23:23:25.843 回答