在Ruby on Rails 中用 xmlrpc 来传输附件(图片)

还是上次的需求,让做Bugzilla的WebService的扩展,Bugzilla的WebService API 中只有create bug的API(不带附件的),现在费让我做一个在创建的时候可以带attachment的API。

在网上找了下,没看到xmlrpc还可以传attachment的例子,都说可以传字符串,数字等基本类型。

但是我想传图片怎么整呢?

1.我先将图片转化成2进制流

2.再将2进制流转化成base64的字编码

3.用xmlrpc把base64编码传输过去(当string传过去)

4.在server端在base64给decode了

5.让后就可以直接当BLOB类型存入mysql数据库了

PS:我没考虑效率之类的,我就先找个方法来实现我的需求,因为把2进制流变成base64编码的时候文件在无形中就变大了。

代码如下:

1.erb文件

Ruby代码  收藏代码
  1. <% form_tag({:action=>'upload'},:multipart => truedo%>  
  2.       <label for="file">File to Upload</label>   
  3.       <%= file_field_tag "file" %>  
  4.       <%=submit_tag "upload" %>  
  5. <% end %>  
 

2.controller文件中

Ruby代码  收藏代码
  1. require "xmlrpc/client"  
  2. require "base64"  
  3. class SoapController < ApplicationController  
  4.   before_filter :get_XMLRPC_server  
  5.     
  6.   def index  
  7.     @products_arr = get_products()  
  8.   end  
  9.     
  10.   def rcp  
  11.   
  12.     @result_1@server.call("Bugzilla.version")  
  13.     @result_2@server.call("Bugzilla.timezone")  
  14.     @result_3@server.call("Bug.get",{:ids=>[1]})  
  15.     @result_4@server.call("Bug.add_attachment",{:id=>1})  
  16.      
  17.     render :action=>'index'  
  18.   end  
  19.     
  20.   def new_bug  
  21.     @product_name = params[:product_name]  
  22.   end  
  23.     
  24.   def create_bug  
  25.       
  26.     bug = {  
  27.         :product     => params[:p],   
  28.         :component   => params[:component],  
  29.         :summary     => params[:summary],  
  30.         :version     => 'unspecified',  
  31.         :description => params[:description],  
  32.         :op_sys      => params[:op_sys],  
  33.         :platform    => params[:platform],     
  34.         :priority    => params[:priority],  
  35.         :severity    => params[:severity]  
  36.     }  
  37.       
  38.     @server.call("Bug.create",bug)  
  39.       
  40.     redirect_to :action=>'index'  
  41.   end  
  42.     
  43.   def upload  
  44.     file = params[:file]  
  45.     file_name = file.original_filename  
  46.     data = encode64(file.read)  
  47.     @server.call("Bug.add_attachment",{:id=>1,:data=>data,:filename=>file_name})  
  48.   end  
  49.     
  50. private   
  51.    
  52.   def login_bugzilla(name,pass,is_remember)  
  53.       
  54.      loginInfo= {  
  55.       :login=>name,  
  56.       :password => pass,  
  57.       :remember => is_remember   
  58.     }  
  59.       
  60.     return  @server.call("User.login",loginInfo)  
  61.   end  
  62.     
  63.   def get_XMLRPC_server  
  64.     @server =  XMLRPC::Client.new"192.168.1.37""/bugzilla/xmlrpc.cgi")  
  65.     login_bugzilla('test1@a.com','111111',false)  
  66.   end  
  67.     
  68.   def get_products  
  69.     ids = @server.call('Product.get_selectable_products')  
  70.     p = @server.call('Product.get',ids)  
  71.     return p["products"]  
  72.   end  
  73.   
  74. end  

 3.在Bugzilla的下的/Bugzilla/WebService/Bug.pm文件下加入扩展的API

Perl代码  收藏代码
  1. 首先   
  2. use MIME::Base64;  
  3.   
  4. sub add_attachment {  
  5.     my ($self,$params) = @_ ;  
  6.   
  7.     my $user = Bugzilla->login(LOGIN_REQUIRED);  
  8.   
  9.     defined $params->{id} || ThrowCodeError('param_required', { param => 'id' });   
  10.     defined $params->{data} || ThrowCodeError('param_required', { param => 'data' });   
  11.     defined $params->{filename} || ThrowCodeError('param_required', { param => 'filename' });  
  12.   
  13.     my $bug = Bugzilla::Bug->check($params->{id});  
  14.   
  15.     Bugzilla->user->can_edit_product($bug->product_id) || ThrowUserError("product_edit_denied", {product => $bug->product});  
  16.   
  17.     my $dbh = Bugzilla->dbh;  
  18.     my ($timestamp) = $dbh->selectrow_array("SELECT NOW()");  
  19.   
  20.     my $data = decode_base64($params->{data});  
  21.     my $filename = $params->{filename};  
  22.     my $description = "test from xmlrpc";  
  23.     my $contenttype = "image/jpeg";  
  24.     my $isurl = 0;  
  25.     my $isprivate = 0;  
  26.   
  27.     $dbh->bz_start_transaction();  
  28.   
  29.      my $sth = $dbh->do(  
  30.         "INSERT INTO attachments  
  31.             (bug_id, creation_ts, modification_time, filename, description,  
  32.              mimetype, ispatch, isurl, isprivate, submitter_id)  
  33.          VALUES (?,?,?,?,?,?,?,?,?,?)", undef, ($bug->bug_id, $timestamp, $timestamp,  
  34.               $filename, $description, $contenttype, 0,  
  35.               $isurl, $isprivate, $user->id));  
  36.     # Retrieve the ID of the newly created attachment record.  
  37.     my $attachid = $dbh->bz_last_key('attachments''attach_id');  
  38.   
  39.     # We only use $data here in this INSERT with a placeholder,  
  40.     # so it's safe.  
  41.     $sth = $dbh->prepare("INSERT INTO attach_data  
  42.                          (id, thedata) VALUES ($attachid, ?)");  
  43.     trick_taint($data);  
  44.     $sth->bind_param(1, $data, $dbh->BLOB_TYPE);  
  45.     $sth->execute();  
  46.    
  47.       
  48.     $dbh->bz_commit_transaction();  
  49.       
  50.   
  51.     return { at => $data };  
  52. }  

以上就实现了怎么可以给一个现有的bug添加一个attachment了。

可能实现的不好,求高人指点更好的解法。

原文地址:https://www.cnblogs.com/lexus/p/2329149.html