• 在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了。

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

  • 相关阅读:
    Apache Commons 工具集使用简介
    程序员最核心的竞争力是什么?
    开发FTP不要使用sun.net.ftp.ftpClient
    Eclipse和MyEclipse工程描述符.classpath和.project和.mymetadata详解(转)
    MAC OS X显示.开头的文件_苹果操作系统显示隐藏文件命令
    再探二分查找
    二叉树的各种操作
    【java】求两个字符串的最长公共子串
    【Java】数组不能通过toString方法转为字符串
    【C语言】数组名传递给函数,数组的sizeof变为4的原因
  • 原文地址:https://www.cnblogs.com/lexus/p/2329149.html
Copyright © 2020-2023  润新知