新手问题 文件上传类型验证

u1453357893 · 2016年04月07日 · 最后由 catherine 回复于 2016年04月08日 · 2928 次阅读

最近做一个和安卓对接的一个业务,有个主要的点儿不熟悉求大神指点!!! 我有个 api,用来《接收安卓那边儿传过来的 csv 文件,然后再上传》 这个逻辑我怎么都不理解,,,问了好多人怎么把文件上传到本地项目,都说和普通文件上传的一样, 我就用了个 Paperclip,可是他调用我的时候怎么执行上传操作啊!!! 例如:以下是我 api 方法

def api_upload_file
  ......
end

写个 from 表单如下:

  <%= form_for @user, url: users_path do |f| %>
    <%= f.file_field :avatar %>
    <%= f.submit %>
<% end %>

model 里边儿的 code 大概如下:

  class Document < ActiveRecord::Base

  has_attached_file :file, 
    :url => "/files/:attachment/:day/:hour/:basename.:extension", # 文件访问路径
    :path => ":rails_root/public/files/:attachment/:day/:basename.:extension" # 文件存放路径 :rails_root 给用户设置存放的root权限
    #validates_attachment_size :avatar, :less_than => 2.megabytes # 文件大小限制
  validates_attachment_content_type :file, content_type: ["text/csv"]

end

在这儿怎么做文件上传操作啊?安卓那边儿写表单吗?求大神指点一下,安卓调了之后,我该怎么具体处理,才能执行上传文件呢?新手希望理解 如果我想对上传的类型做判断,如果不是 csv 文件,想返回给安卓提示信息,,,该怎么做呢?

好像没人搭理哎

记得之前做过类似的。大概逻辑是,

后台:写一个 update 操作,更新上传的文件名。 安卓那边直接提交表单,表单里需要传的什么参数,就参考用辅助方法生成的表单传的参数吧,本质上都一样。楼主参考下面这段模拟吧

when 'http'
    file = "./u.png"

    header = {"Content-Type" => "multipart/form-data, boundary=#{BOUNDARY}"}
    post_body = []
    post_body << "--#{BOUNDARY}\r\n"
    post_body << "Content-Disposition: form-data; name=\"user[photo]\"; filename=\"#{File.basename(file)}\"\r\n"
    post_body << "Content-Type: image/png\r\n\r\n"
    post_body << File.read(file)
    post_body << "\r\n\r\n--#{BOUNDARY}--\r\n"

    uri = URI.parse("#{ROOT}/api/userphoto_update?client_uuid=#{CUUID}&latitude=#{LATITUDE}&longitude=#{LONGITUDE}")
    http = Net::HTTP.new(uri.host, uri.port)
    req = Net::HTTP::Put.new(uri.request_uri, header)
    req.body = post_body.join
    req.basic_auth("#{LOGINNAME}", "#{PASSWORD}")
    r = http.request(req)

    if r.code.to_i == 200
        $messages = $messages + "\n" if $messages != ""
        $messages = $messages + "#{api_type} OK - #{r.code}: #{r.message}"
    else
        $messages = $messages + "\n" if $messages != ""
        $messages = $messages + "#{api_type} WARNING - #{r.code}: #{r.message}"
    end
end

这大概是半年前的项目里的一个小功能了,当时是需要给公众号里的页面提供一个用户上传头像还是照片的功能。

如果我没有理解错的话,你是做 Server 端实现。

其他人说的是对的,Android 跟普通的表单上传是一样都是通过 HTTP 协议跟服务端端打交道,当需要处理上传文件的时候,需要使用 multipart 方式来传输内容。

<%= form_for @user, url: users_path, multipart: true  do |f| %>
    <%= f.file_field :avatar %>
    <%= f.submit %>
<% end %>

Android 只需要构建出这个 HTTP Request 请求,同样通过 multipart 的方式附带 csv 文件作为附件一起发送到服务端就可以了。我没有写过 Android,只写过 iOS 的类似功能,基本上一个正常的 HTTP Client 库都应该能很方便的写出带 multipart 的请求。

#2 楼 @catherine 你贴的 code 应该是安卓那边儿处理的吧?可是我 api 里边儿具体该怎么做?

#3 楼 @lgn21st 我只给安卓那边儿一个 api 的 url?可是 api 这块儿怎么调用文件上传的操作啊

#3 楼 @lgn21st 题主似乎只需要上传 CSV 纯文本,用 HTTP POST 就可以了 curl -v -X POST :8080 -d "a,b,c\n1,2,3" -H "Content-Type":text/csv

#5 楼 @u1453357893 你要解决两个问题对么

  1. 实现一个可以接收 android 上传 csv 的 API,然后告诉 android 怎么调用这个 API。
  2. 实现一个把接收到的 csv 上传到其他地方的功能。

关于 1,就是一个普通的 RESTful 的 API 实现,具体可以搜到大量的教程。 关于 2,任何一个 Ruby 的 HTTP Client,比如 Ruby 自带的 Net::HTTP 就能做到,具体可以搜到大量教程。

#7 楼 @lgn21st 谢谢,我自己找找吧

#6 楼 @nouse curl 一般都是在本地测用的吧?

#10 楼 @u1453357893 后台挺简单的,就只有一句话,update 一下大概是文件名到对应字段。回复里的代码是模拟前端提交文件,测试 api 用的。

之前项目做的是前后端分离,有点久了,前端是别人写的,所以只知道后台部分。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号