作为 votable JSON put
Acts as votable JSON put
我有一个可用的 rails 应用程序,它是一个带有评论和 upvoting/downvoting 的博客。
移动组件供用户注销in/log、查看文章和upvote/downvote,在此阶段不添加文章或评论。
我已经使用简单的令牌身份验证 gem 实现了 json 登录,我可以获得文章及其 upvotes/downvotes 一切正常,但这是我的问题:
如何恢复 post json 值?我的 json 代码在 Android 到 post 或推送 json 值中工作,但我如何构建正确的字符串来推回?放回去的正确参数是什么?
非常感谢。
这来自 rails 服务器日志:
有效的 html 赞成票:
Started PUT "/articles/5/like" for 137.147.172.125 at 2016-03-12 09:34:43 +0000
Cannot render console from 137.147.172.125! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by ArticlesController#upvote as HTML
Parameters: {"authenticity_token"=>"4eC8xgC+1CBb51gKO7ZRzjL1BGOF6TYTnbqQcJ3evxvpmGcguYHBNYSn9v3LJMfoo3F29frntwzgyLoeI9oaLg==", "id"=>"5"}
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
Article Load (0.1ms) SELECT "articles".* FROM "articles" WHERE "articles"."id" = ? ORDER BY "articles"."created_at" DESC LIMIT 1 [["id", 5]]
(0.3ms) SELECT COUNT(*) FROM "votes" WHERE "votes"."votable_id" = ? AND "votes"."votable_type" = ? AND "votes"."voter_id" = ? AND "votes"."voter_type" = ? AND "votes"."vote_scope" IS NULL [["votable_id", 5], ["votable_type", "Article"], ["voter_id", 1], ["voter_type", "User"]]
(0.2ms) begin transaction
SQL (0.6ms) INSERT INTO "votes" ("votable_id", "votable_type", "voter_id", "voter_type", "vote_flag", "vote_weight", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?) [["votable_id", 5], ["votable_type", "Article"], ["voter_id", 1], ["voter_type", "User"], ["vote_flag", "t"], ["vote_weight", 1], ["created_at", "2016-03-12 09:34:43.393685"], ["updated_at", "2016-03-12 09:34:43.393685"]]
(11.4ms) commit transaction
Redirected to https://completerubyonrailscourse-adam1st.c9users.io/articles/5
Completed 302 Found in 187ms (ActiveRecord: 13.2ms)
这是我的 android 代码尝试将 json 数据推送回 rails 服务器的时候:
Started PUT "/articles/5/like" for 49.199.131.149 at 2016-03-12 10:20:16 +0000
Cannot render console from 49.199.131.149! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by ArticlesController#upvote as JSON
Parameters: {"votes"=>{"votable_id"=>"5", "votable_type"=>"Article", "voter_id"=>"1", "voter_type"=>"User", "vote_flag"=>"t", "vote_weight"=>"1", "created_at"=>"2016-03-12 21:20:13.679000", "updated_at"=>"2016-03-12 21:20:13.679000"}, "id"=>"5", "article"=>{}}
Can't verify CSRF token authenticity
Completed 401 Unauthorized in 2ms (ActiveRecord: 0.0ms)
那么如何将其放入 json 数据中?
Parameters:{"authenticity_token"=>"4eC8xgC+1CBb51gKO7ZRzjL1BGOF6TYTnbqQcJ3evxvpmGcguYHBNYSn9v3LJMfoo3F29frntwzgyLoeI9oaLg==", "id"=>"5"}
来自文章管理员:
before_action :authenticate_user!, :except => [:index, :show]
before_filter :set_article, only: [:show, :edit, :update, :destroy, :upvote, :downvote]
.
.
.
def upvote
@article.upvote_by current_user
flash[:success] = "Successfully liked"
respond_to do |format|
format.html {redirect_to :back }
format.json { render json: { count: @article.liked_count } }
end
end
def downvote
@article.downvote_by current_user
flash[:success] = "Successfully disliked"
respond_to do |format|
format.html {redirect_to :back }
format.json { render json: { count: @article.disliked_count } }
end
end
来自关于投票的show.html.erb:
<%= link_to like_article_path(@article), method: :put, class: 'voting' do %>
<i class="fa fa-thumbs-up"></i>
<%= @article.get_upvotes.size %>
<% end %>
<%= link_to dislike_article_path(@article), method: :put, class: 'voting' do %>
<i class="fa fa-thumbs-down"></i>
<%= @article.get_downvotes.size %>
<% end %>
Android PUT 代码(一些值硬编码用于测试):
private class VoteTask extends UrlJsonAsyncTask {
public VoteTask(Context context) {
super(context);
}
@Override
protected JSONObject doInBackground(String... urls) {
HttpClient client = new DefaultHttpClient();
HttpPut put = new HttpPut(urls[0]);
JSONObject holder = new JSONObject();
JSONObject voteObj = new JSONObject();
String response = null;
JSONObject json = new JSONObject();
try {
try {
// setup the returned values in case
// something goes wrong
json.put("success", false);
json.put("info", "Something went wrong. Retry!");
// add the user email and password to
// the params
voteObj.put("votable_id",articleId);
voteObj.put("votable_type", "Article");
voteObj.put("voter_id", "1");
voteObj.put("voter_type", "User");
voteObj.put("vote_flag", "t");
voteObj.put("vote_weight", "1");
voteObj.put("created_at", strDate);
voteObj.put("updated_at", strDate);
holder.put("votes", voteObj);
StringEntity se = new StringEntity(holder.toString());
put.setEntity(se);
// setup the request headers
put.setHeader("Accept", "application/json");
put.setHeader("Content-Type", "application/json");
response = String.valueOf(client.execute(put));
json = new JSONObject(response);
} catch (IOException e) {
e.printStackTrace();
Log.e("IO", "" + e);
}
} catch (JSONException e) {
e.printStackTrace();
Log.e("JSON", "" + e);
}
return json;
}
将此添加到您的 application_controller.rb
文件中
protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format == 'application/json' }
我去了 Simple token authentication https://github.com/gonzalo-bulnes/simple_token_authentication 的 git 看到了这个。
身份验证方法 2:请求 Headers
您还可以使用请求 headers(在针对 API 进行身份验证时可能更简单):
X-User-Email 爱丽丝@example.com
X-User-Token 1G8_s7P-V-4MGojaKD7a
所以我在 headers 中将其放入我的投票任务中,然后再进行投票,它奏效了。
private class VoteTask extends UrlJsonAsyncTask {
public VoteTask(Context context) {
super(context);
}
@Override
protected JSONObject doInBackground(String... urls) {
DefaultHttpClient webClient = new DefaultHttpClient();
HttpPut put = new HttpPut(urls[0]);
JSONObject holder = new JSONObject();
JSONObject voteObj = new JSONObject();
String response = null;
JSONObject json = new JSONObject();
try {
try {
// setup the returned values in case
// something goes wrong
json.put("success", false);
json.put("info", "Something went wrong. Retry!");
//get stored values to prove the user is authorised
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
String id = sharedPreferences.getString("userId", "default value");
String authToken = sharedPreferences.getString("AuthToken", "default value");
String email = sharedPreferences.getString("email", "default value");
voteObj.put("votable_id",articleId);
voteObj.put("votable_type", "Article");
voteObj.put("voter_id", id);
voteObj.put("voter_type", "User");
voteObj.put("vote_flag", voteFlag);
voteObj.put("vote_weight", "1");
holder.put("votes", voteObj);
holder.put("article", articleId);
StringEntity se = new StringEntity(holder.toString());
put.setEntity(se);
// setup the request headers
put.setHeader("Accept", "application/json");
put.setHeader("Content-Type", "application/json");
// add email and auth token to validate
put.setHeader("X-User-Email", email);
put.setHeader("X-User-Token", authToken);
//response = webClient.execute(put);
//json = new JSONObject(response);
response = String.valueOf(webClient.execute(put));
json = new JSONObject(response);
} catch (HttpResponseException e) {
e.printStackTrace();
Log.e("ClientProtocol", "" + e);
json.put("info", "Email and/or password are invalid. Retry!");
} catch (IOException e) {
e.printStackTrace();
Log.e("IO", "" + e);
}
} catch (JSONException e) {
e.printStackTrace();
Log.e("JSON", "" + e);
}
return json;
}
我有一个可用的 rails 应用程序,它是一个带有评论和 upvoting/downvoting 的博客。 移动组件供用户注销in/log、查看文章和upvote/downvote,在此阶段不添加文章或评论。
我已经使用简单的令牌身份验证 gem 实现了 json 登录,我可以获得文章及其 upvotes/downvotes 一切正常,但这是我的问题:
如何恢复 post json 值?我的 json 代码在 Android 到 post 或推送 json 值中工作,但我如何构建正确的字符串来推回?放回去的正确参数是什么?
非常感谢。
这来自 rails 服务器日志:
有效的 html 赞成票:
Started PUT "/articles/5/like" for 137.147.172.125 at 2016-03-12 09:34:43 +0000
Cannot render console from 137.147.172.125! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by ArticlesController#upvote as HTML
Parameters: {"authenticity_token"=>"4eC8xgC+1CBb51gKO7ZRzjL1BGOF6TYTnbqQcJ3evxvpmGcguYHBNYSn9v3LJMfoo3F29frntwzgyLoeI9oaLg==", "id"=>"5"}
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
Article Load (0.1ms) SELECT "articles".* FROM "articles" WHERE "articles"."id" = ? ORDER BY "articles"."created_at" DESC LIMIT 1 [["id", 5]]
(0.3ms) SELECT COUNT(*) FROM "votes" WHERE "votes"."votable_id" = ? AND "votes"."votable_type" = ? AND "votes"."voter_id" = ? AND "votes"."voter_type" = ? AND "votes"."vote_scope" IS NULL [["votable_id", 5], ["votable_type", "Article"], ["voter_id", 1], ["voter_type", "User"]]
(0.2ms) begin transaction
SQL (0.6ms) INSERT INTO "votes" ("votable_id", "votable_type", "voter_id", "voter_type", "vote_flag", "vote_weight", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?) [["votable_id", 5], ["votable_type", "Article"], ["voter_id", 1], ["voter_type", "User"], ["vote_flag", "t"], ["vote_weight", 1], ["created_at", "2016-03-12 09:34:43.393685"], ["updated_at", "2016-03-12 09:34:43.393685"]]
(11.4ms) commit transaction
Redirected to https://completerubyonrailscourse-adam1st.c9users.io/articles/5
Completed 302 Found in 187ms (ActiveRecord: 13.2ms)
这是我的 android 代码尝试将 json 数据推送回 rails 服务器的时候:
Started PUT "/articles/5/like" for 49.199.131.149 at 2016-03-12 10:20:16 +0000
Cannot render console from 49.199.131.149! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by ArticlesController#upvote as JSON
Parameters: {"votes"=>{"votable_id"=>"5", "votable_type"=>"Article", "voter_id"=>"1", "voter_type"=>"User", "vote_flag"=>"t", "vote_weight"=>"1", "created_at"=>"2016-03-12 21:20:13.679000", "updated_at"=>"2016-03-12 21:20:13.679000"}, "id"=>"5", "article"=>{}}
Can't verify CSRF token authenticity
Completed 401 Unauthorized in 2ms (ActiveRecord: 0.0ms)
那么如何将其放入 json 数据中?
Parameters:{"authenticity_token"=>"4eC8xgC+1CBb51gKO7ZRzjL1BGOF6TYTnbqQcJ3evxvpmGcguYHBNYSn9v3LJMfoo3F29frntwzgyLoeI9oaLg==", "id"=>"5"}
来自文章管理员:
before_action :authenticate_user!, :except => [:index, :show]
before_filter :set_article, only: [:show, :edit, :update, :destroy, :upvote, :downvote]
.
.
.
def upvote
@article.upvote_by current_user
flash[:success] = "Successfully liked"
respond_to do |format|
format.html {redirect_to :back }
format.json { render json: { count: @article.liked_count } }
end
end
def downvote
@article.downvote_by current_user
flash[:success] = "Successfully disliked"
respond_to do |format|
format.html {redirect_to :back }
format.json { render json: { count: @article.disliked_count } }
end
end
来自关于投票的show.html.erb:
<%= link_to like_article_path(@article), method: :put, class: 'voting' do %>
<i class="fa fa-thumbs-up"></i>
<%= @article.get_upvotes.size %>
<% end %>
<%= link_to dislike_article_path(@article), method: :put, class: 'voting' do %>
<i class="fa fa-thumbs-down"></i>
<%= @article.get_downvotes.size %>
<% end %>
Android PUT 代码(一些值硬编码用于测试):
private class VoteTask extends UrlJsonAsyncTask {
public VoteTask(Context context) {
super(context);
}
@Override
protected JSONObject doInBackground(String... urls) {
HttpClient client = new DefaultHttpClient();
HttpPut put = new HttpPut(urls[0]);
JSONObject holder = new JSONObject();
JSONObject voteObj = new JSONObject();
String response = null;
JSONObject json = new JSONObject();
try {
try {
// setup the returned values in case
// something goes wrong
json.put("success", false);
json.put("info", "Something went wrong. Retry!");
// add the user email and password to
// the params
voteObj.put("votable_id",articleId);
voteObj.put("votable_type", "Article");
voteObj.put("voter_id", "1");
voteObj.put("voter_type", "User");
voteObj.put("vote_flag", "t");
voteObj.put("vote_weight", "1");
voteObj.put("created_at", strDate);
voteObj.put("updated_at", strDate);
holder.put("votes", voteObj);
StringEntity se = new StringEntity(holder.toString());
put.setEntity(se);
// setup the request headers
put.setHeader("Accept", "application/json");
put.setHeader("Content-Type", "application/json");
response = String.valueOf(client.execute(put));
json = new JSONObject(response);
} catch (IOException e) {
e.printStackTrace();
Log.e("IO", "" + e);
}
} catch (JSONException e) {
e.printStackTrace();
Log.e("JSON", "" + e);
}
return json;
}
将此添加到您的 application_controller.rb
文件中
protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format == 'application/json' }
我去了 Simple token authentication https://github.com/gonzalo-bulnes/simple_token_authentication 的 git 看到了这个。
身份验证方法 2:请求 Headers
您还可以使用请求 headers(在针对 API 进行身份验证时可能更简单):
X-User-Email 爱丽丝@example.com
X-User-Token 1G8_s7P-V-4MGojaKD7a
所以我在 headers 中将其放入我的投票任务中,然后再进行投票,它奏效了。
private class VoteTask extends UrlJsonAsyncTask {
public VoteTask(Context context) {
super(context);
}
@Override
protected JSONObject doInBackground(String... urls) {
DefaultHttpClient webClient = new DefaultHttpClient();
HttpPut put = new HttpPut(urls[0]);
JSONObject holder = new JSONObject();
JSONObject voteObj = new JSONObject();
String response = null;
JSONObject json = new JSONObject();
try {
try {
// setup the returned values in case
// something goes wrong
json.put("success", false);
json.put("info", "Something went wrong. Retry!");
//get stored values to prove the user is authorised
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
String id = sharedPreferences.getString("userId", "default value");
String authToken = sharedPreferences.getString("AuthToken", "default value");
String email = sharedPreferences.getString("email", "default value");
voteObj.put("votable_id",articleId);
voteObj.put("votable_type", "Article");
voteObj.put("voter_id", id);
voteObj.put("voter_type", "User");
voteObj.put("vote_flag", voteFlag);
voteObj.put("vote_weight", "1");
holder.put("votes", voteObj);
holder.put("article", articleId);
StringEntity se = new StringEntity(holder.toString());
put.setEntity(se);
// setup the request headers
put.setHeader("Accept", "application/json");
put.setHeader("Content-Type", "application/json");
// add email and auth token to validate
put.setHeader("X-User-Email", email);
put.setHeader("X-User-Token", authToken);
//response = webClient.execute(put);
//json = new JSONObject(response);
response = String.valueOf(webClient.execute(put));
json = new JSONObject(response);
} catch (HttpResponseException e) {
e.printStackTrace();
Log.e("ClientProtocol", "" + e);
json.put("info", "Email and/or password are invalid. Retry!");
} catch (IOException e) {
e.printStackTrace();
Log.e("IO", "" + e);
}
} catch (JSONException e) {
e.printStackTrace();
Log.e("JSON", "" + e);
}
return json;
}