OK,交給File類別、ActionController::UploadedFile模組與send_file()方法吧!
1. 建立RESTful SOA Service - rails new
- 開啟終端機
- 輸入rails new attachment_service,建立名為attachment_service的SOA服務
- 於\config找到routes.rb
- 接下來我們將透過"post"和"get"方法宣告上傳與下載的URI並對應到Controller,讓Controller對資源的請求進行回應,如下:
AttachmentService::Application.routes.draw do
#上傳URI
post 'attachments' => 'attachments#upload', :defaults => {:format => "json"}
#下載URI
get 'attachments/:id' => 'attachments#download'
end
3. Model儲存上傳的檔案資訊 - rails generate model
- 開啟終端機,並切換到attachment_service目錄下
- 輸入"rails generate model attachment original_filename:string filename:string"指令並執行,建立名為attachment的Model,目的是用來保存上傳檔案的資訊,其中original_filename保存原始的檔名,而filename則是保存實際儲存的檔名。
- 輸入"rake db:migrate"指令並執行,實際建立attachments資料表
4. Controller處理URI請求 - rails generate controller
- 開啟終端機,並切換到attachment_service目錄下
- 敲入"rails generate controller attachments"指令並執行,建立名為attachments的Controller
- 於attachment_service\app\controllers,開啟attachments_controller.rb
- 加入upload方法,其會透過file參數取出上傳的檔案,而後透過File類別實際儲存資料到file目錄下,檔案的資訊在透過Attachment model存在資料庫中,其中的original_filename欄位保存原始上傳的檔案名稱,filename欄位保存實際儲存在server上的檔案名稱
- 加入download方法,透過id取得Attachment物件,找出檔案的資訊,在透過send_file()方法將檔案傳回
class AttachmentsController < ApplicationController
def upload
#取得上傳的檔案,
#其自動會對應到ActionController::UploadedFile模組的物件
@uploaded_file = params[:file]
#建立attachment model物件
@attachment = Attachment.new
#取得原始檔名
@attachment.original_filename = @uploaded_file.original_filename
if (@attachment.save)
#取得副檔名,在與id組合存成新檔名
@extname = File.extname(@uploaded_file.original_filename)
@filename = @attachment.id.to_s + @extname
@attachment.filename = @filename
#再次存檔至資料庫
@attachment.save
#將檔案寫入file目錄下
File.open(Rails.root.join('file', @attachment.filename), 'wb') do |file|
file.write(@uploaded_file.read)
end
#回傳attachment資訊
render json:@attachment
else
render json:@attachment.errors
end
end
def download
#依id取得attachment資訊
@attachment = Attachment.find(params[:id])
#透過send_file方法傳回此檔案,
#透過:filename參數的設定,
#將檔名變更回原始的檔名回傳。
send_file(Rails.root.join('file', @attachment.filename), :filename => @attachment.original_filename)
end
end
- 當然,最後別忘了在attachment_service目錄下建立file目錄
4. 啟動伺服器 - rails server
- 輸入rails server,透過rails server啟動伺服器,其預設的port為3000:
5. 測試 - Postman
- 上傳檔案
- URI:http://localhost:3000/attachments
- HTTP Method:POST
- Data:file => small_enginer.png
- 下載檔案
- URI:http://localhost:3000/attachments/1
- HTTP Method:GET
- Data:(none)