最近想弄个能访问 Internet 的 Android 应用,因为求快所以用了 Ruby on Rails 来提供 HTTP
资源。这方面的资料还是比较少的,所以把尝试的过程记录下来。
1 使用 Ruby on Rails 构建 Web Application
1.1 新建 Web Application
rails new Test
cd Test
1.2 生成 product
rails generate scaffold product reference:string quantity:decimal
rake db:migrate
启动服务
rails server
打开http://localhost:3000/products
应该可以看到以下信息(这个就是GET的结果啦,只不过现在还没有记录):
在网页上添加一条记录,单击“New Product”,会转到“http://localhost:3000/products/new”,在里面填写信息后单击“Greate Product”(这样就提交了一个
POST):
也就是说,网页端的 GET 和 POST 都是可以执行的。
1.3 使用 Json 格式传输数据
先试试 GET Json 格式的数据
打开:http://localhost:3000/products/1.json
可以看到,使用 ruby on rails 是可以直接获得 Json 数据的,这是为什么呢?
为了弄清楚 Json 数据是怎么来的,先查看 routes
rake routes
显示出以下结果:
所以输入的 http://localhost:3000/products/1.json 对应的是 Controller 里面的
show,在代码里找到show(Test/app/controllers/products_controller.rb):
咦!什么情况?啥都不写就能直接支持 Json ?这也太牛逼了吧。
再试试 Post Json 格式的数据
前面已经知道,用网页可以提交一个 POST,先跟踪一下下这个 POST,用开发者工具查看网络知道页面提交的时候提交了一个 POST:
这个 POST 根据前面的 Routes 应该是给了 controller 里的 create。
所以是 @product = Product.new(product_params) 创建对象,@product.save 保存对象。。那么
product_params 怎么来的呢?
好吧,是这样来的。。。
嗯。。还是没有解决我想要的 Json 传输方法,后来还是搜索找大神。。。
在 Test/app/controllers/products_controller.rb
中添加以下代码,用于接受 Android App 提交的 Json 数据。
def create_from_app
data_json=JSON.parse request.body.read
@product = Product.new(data_json)
@product.save
end
1.4 测试 GET 和 POST 是否正常
测试使用的是火狐的 Poster 工具。
测试 GET
测试 POST
补上一段小插曲:直接提交 POST 时是出错的:
把出错的内容粘贴出来存成html,发现是这个错误:
百度求大神,得到这样的答案:
这是从rails 2.0
开始包含的一个新功能,目的在于防止CSRF(Cross-Site Request Forgery)攻击
请原谅我直接暴力地选择了禁用
CSRF 的方式,找到Test/app/controllers/products_controller.rb,插入代码
protect_from_forgery :except => :index# you can disable csrf protection on controller-by-controller basis:
skip_before_filter :verify_authenticity_token
重启 rails server
问题解决,再次提交 POST:
也就是说 Android 客户端只要能按照以上格式发送 HTTP 请求就可以了。
2 使用 Android 客户端访问 HTTP 资源
2.1 获取访问网络的权限
在 AndroidManifest.xml 文件中添加以下行
<uses-permission android:name="android.permission.INTERNET"/>
2.2 使用 Android 客户端提交 GET 请求
try {
final String url = "http://192.168.0.138:3000/products/" + message
+ ".json";Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = new DefaultHttpClient()
.execute(httpGet);
if (httpResponse.getStatusLine().getStatusCode() == 200) {
result = EntityUtils.toString(httpResponse
.getEntity());}
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
2.3 使用 Android 客户端提交 POST 请求
try{
Thread threadPost = new Thread(new Runnable() {
@Override
public void run() {
try {
final String url = "http://192.168.0.138:3000/products";
HttpPost httpPost = new HttpPost(url);JSONObject json = new JSONObject();
json.accumulate("reference", "888");
json.accumulate("quantity", "8");
JSONObject response = null;
StringEntity s = new StringEntity(json.toString());
s.setContentEncoding("UTF-8");
s.setContentType("application/json");
httpPost.setEntity(s);HttpResponse httpResponse = new DefaultHttpClient()
.execute(httpPost);
if (httpResponse.getStatusLine().getStatusCode() == 200) {
result = EntityUtils.toString(httpResponse.getEntity());
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
threadPost.start();
threadPost.join();
} catch (Exception e) {
e.printStackTrace();
}
使用 Android 客户端向 Ruby on rails 构建的 Web Application 提交 HTTP GET 和
HTTP POST 请求,布布扣,bubuko.com
使用 Android 客户端向 Ruby on rails 构建的 Web Application 提交 HTTP GET 和
HTTP POST 请求