我如何 POST json 数据从 android 应用程序到 Rails 服务器上的 Ruby
How can I POST json data from android app to Ruby on Rails server
我正在尝试将 json 数据发送到我的 RoR 服务器,以便在服务器收到 POST 请求时创建一个新对象。我是 RoR 的新手,所以我不确定如何正确设置它。
我一直在这里搜索其他 posts 有一段时间应用类似问题的解决方案,但我所做的似乎没有任何效果。
最后 Rails - 我专门为此设置了一条路线。
在routes.rb
post '/api' => 'expenses#post_json_expense'
在expenses_controller.rb
# For creating an expense from the android app
def post_json_expense
Expense.new(expense_params)
end
# Never trust parameters from the scary internet, only allow the white list through.
def expense_params
params.require(:expense).permit(:user_id, :amount, :category, :description)
end
我还关闭了令牌身份验证,以防出现问题。
在config/application
config.action_controller.allow_forgery_protection = false
在 android 方面,我正在使用 Volley 发送 POST 请求
private void saveExpense () {
// Build the URL
String url = "https://my-project-url.herokuapp.com/api";
Log.i("API_REQUEST", url);
EditText etAmount = findViewById(R.id.et_amount);
EditText etDescription = findViewById(R.id.et_description);
EditText etCategory = findViewById(R.id.et_category);
// Get values from the EditTexts
double amount = Double.parseDouble(etAmount.getText().toString());
String description = etDescription.getText().toString().trim();
String category = etCategory.getText().toString().trim();
// If something was entered into all of the fields
if (amount > 0 && !description.isEmpty() && !category.isEmpty()) {
// Convert field entries into a JSON object
JSONObject expenseData = new JSONObject();
JSONObject expenseObject = new JSONObject();
try {
expenseData.put("user_id", user_id);
expenseData.put("amount", amount);
expenseData.put("description", description);
expenseData.put("category", category);
expenseObject.put("expense", expenseData);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.PUT, url, expenseObject, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Toast.makeText(EditExpenseActivity.this, "POST Successful", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(EditExpenseActivity.this, MainActivity.class);
startActivity(intent);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(EditExpenseActivity.this, "POST Unsuccessful", Toast.LENGTH_SHORT).show();
}
}) {
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/json");
return params;
}
};
// Make the API request
RequestQueue queue = Volley.newRequestQueue(this);
queue.add(jsonObjectRequest);
}
}
每次尝试向应用程序 post 发送数据时,我都会收到错误响应。
我哪里错了?我对 rails 很陌生,这是我第一次尝试构建 API,所以我不确定自己做错了什么。
欢迎来到S.O.!
所以,这里有一些事情需要解决。对于初学者,在您的控制器中:
# For creating an expense from the android app
def post_json_expense
Expense.new(expense_params)
end
所以,首先,这里调用Expense.new
只会新建一个object,不会持久化到数据库;您还需要致电 save
来执行此操作。
接下来,您不会向调用方返回任何类型的响应。也许返回像新费用的 id 这样的东西是合适的,或者是费用本身。我建议像这样构造调用:
# For creating an expense from the android app
def post_json_expense
expense = Expense.new(expense_params)
unless expense.save
# TODO: Return an error status with some useful details
# You can get some from expense.errors
return render status: 400, json: { error: true }
end
# Render a JSON representation of the expense on successful save
render json: expense.as_json
end
接下来,在客户端,你发送Content-type
headers,这很好,但你也可以发送Accept
headers,这会提示服务器端关于您希望收到什么:
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/json");
params.put("Accept", "application/json");
return params;
}
最后,您已将方法分配给服务器上的 POST 路由:
post '/api' => 'expenses#post_json_expense'
但是您在您的应用中将其作为 PUT 调用:
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.PUT, url, expenseObject, new Response.Listener<JSONObject>() {
因此,URL 处没有 PUT
路由,因此请求总是失败。
解决这些问题应该会让您获得成功的响应。
就个人而言,我发现使用像 curl
这样的简单实用程序通常有助于调试此类通信错误,当您不知道问题是 app-side 编码问题还是server-side 编码问题(或两者都有)。您可以通过使用诸如 curl
之类的东西来消除变量,您可以确信它是有效的,然后从那里进行调试。
希望这对您有所帮助!
我正在尝试将 json 数据发送到我的 RoR 服务器,以便在服务器收到 POST 请求时创建一个新对象。我是 RoR 的新手,所以我不确定如何正确设置它。
我一直在这里搜索其他 posts 有一段时间应用类似问题的解决方案,但我所做的似乎没有任何效果。
最后 Rails - 我专门为此设置了一条路线。
在routes.rb
post '/api' => 'expenses#post_json_expense'
在expenses_controller.rb
# For creating an expense from the android app
def post_json_expense
Expense.new(expense_params)
end
# Never trust parameters from the scary internet, only allow the white list through.
def expense_params
params.require(:expense).permit(:user_id, :amount, :category, :description)
end
我还关闭了令牌身份验证,以防出现问题。
在config/application
config.action_controller.allow_forgery_protection = false
在 android 方面,我正在使用 Volley 发送 POST 请求
private void saveExpense () {
// Build the URL
String url = "https://my-project-url.herokuapp.com/api";
Log.i("API_REQUEST", url);
EditText etAmount = findViewById(R.id.et_amount);
EditText etDescription = findViewById(R.id.et_description);
EditText etCategory = findViewById(R.id.et_category);
// Get values from the EditTexts
double amount = Double.parseDouble(etAmount.getText().toString());
String description = etDescription.getText().toString().trim();
String category = etCategory.getText().toString().trim();
// If something was entered into all of the fields
if (amount > 0 && !description.isEmpty() && !category.isEmpty()) {
// Convert field entries into a JSON object
JSONObject expenseData = new JSONObject();
JSONObject expenseObject = new JSONObject();
try {
expenseData.put("user_id", user_id);
expenseData.put("amount", amount);
expenseData.put("description", description);
expenseData.put("category", category);
expenseObject.put("expense", expenseData);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.PUT, url, expenseObject, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Toast.makeText(EditExpenseActivity.this, "POST Successful", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(EditExpenseActivity.this, MainActivity.class);
startActivity(intent);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(EditExpenseActivity.this, "POST Unsuccessful", Toast.LENGTH_SHORT).show();
}
}) {
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/json");
return params;
}
};
// Make the API request
RequestQueue queue = Volley.newRequestQueue(this);
queue.add(jsonObjectRequest);
}
}
每次尝试向应用程序 post 发送数据时,我都会收到错误响应。 我哪里错了?我对 rails 很陌生,这是我第一次尝试构建 API,所以我不确定自己做错了什么。
欢迎来到S.O.!
所以,这里有一些事情需要解决。对于初学者,在您的控制器中:
# For creating an expense from the android app
def post_json_expense
Expense.new(expense_params)
end
所以,首先,这里调用Expense.new
只会新建一个object,不会持久化到数据库;您还需要致电 save
来执行此操作。
接下来,您不会向调用方返回任何类型的响应。也许返回像新费用的 id 这样的东西是合适的,或者是费用本身。我建议像这样构造调用:
# For creating an expense from the android app
def post_json_expense
expense = Expense.new(expense_params)
unless expense.save
# TODO: Return an error status with some useful details
# You can get some from expense.errors
return render status: 400, json: { error: true }
end
# Render a JSON representation of the expense on successful save
render json: expense.as_json
end
接下来,在客户端,你发送Content-type
headers,这很好,但你也可以发送Accept
headers,这会提示服务器端关于您希望收到什么:
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/json");
params.put("Accept", "application/json");
return params;
}
最后,您已将方法分配给服务器上的 POST 路由:
post '/api' => 'expenses#post_json_expense'
但是您在您的应用中将其作为 PUT 调用:
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.PUT, url, expenseObject, new Response.Listener<JSONObject>() {
因此,URL 处没有 PUT
路由,因此请求总是失败。
解决这些问题应该会让您获得成功的响应。
就个人而言,我发现使用像 curl
这样的简单实用程序通常有助于调试此类通信错误,当您不知道问题是 app-side 编码问题还是server-side 编码问题(或两者都有)。您可以通过使用诸如 curl
之类的东西来消除变量,您可以确信它是有效的,然后从那里进行调试。
希望这对您有所帮助!