在Ruby on Rails 中用 xmlrpc 来传输附件(图片)
http://hedahai119.iteye.com/blog/619972 在Ruby on Rails 中用 xmlrpc 来传输附件(图片) 博客分类: ruby on rails
Rails Ruby WebService MySQL CGI
还是上次的需求,让做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代码
<% form_tag({ :action => 'upload' }, :multipart => true ) do %> <label for = "file" > File to Upload</label> <%= file_field_tag "file" %> <%=submit_tag "upload" %> <% end %>2.controller文件中
Ruby代码
require "xmlrpc/client" require "base64" class SoapController < ApplicationController before_filter :get_XMLRPC_server def index @products_arr = get_products() end def rcp @result_1 = @server .call( "Bugzilla.version" ) @result_2 = @server .call( "Bugzilla.timezone" ) @result_3 = @server .call( "Bug.get" ,{ :ids =>[1]}) @result_4 = @server .call( "Bug.add_attachment" ,{ :id =>1}) render :action => 'index' end def new_bug @product_name = params[ :product_name ] end def create_bug bug = { :product => params[ :p ], :component => params[ :component ], :summary => params[ :summary ], :version => 'unspecified' , :description => params[ :description ], :op_sys => params[ :op_sys ], :platform => params[ :platform ], :priority => params[ :priority ], :severity => params[ :severity ] } @server .call( "Bug.create" ,bug) redirect_to :action => 'index' end def upload file = params[ :file ] file_name = file.original_filename data = encode64(file.read) @server .call( "Bug.add_attachment" ,{ :id =>1, :data =>data, :filename =>file_name}) end private def login_bugzilla(name,pass,is_remember) loginInfo= { :login =>name, :password => pass, :remember => is_remember } return @server .call( "User.login" ,loginInfo) end def get_XMLRPC_server @server = XMLRPC::Client. new ( "192.168.1.37" , "/bugzilla/xmlrpc.cgi" ) login_bugzilla( 'test1@a.com' , '111111' , false ) end def get_products ids = @server .call( 'Product.get_selectable_products' ) p = @server .call( 'Product.get' ,ids) return p[ "products" ] end end3.在Bugzilla的下的/Bugzilla/WebService/Bug.pm文件下加入扩展的API
Perl代码
首先 use MIME::Base64; sub add_attachment { my ($self,$params) = @_ ; my $user = Bugzilla->login(LOGIN_REQUIRED); defined $params->{id} || ThrowCodeError( 'param_required' , { param => 'id' }); defined $params->{data} || ThrowCodeError( 'param_required' , { param => 'data' }); defined $params->{filename} || ThrowCodeError( 'param_required' , { param => 'filename' }); my $bug = Bugzilla::Bug->check($params->{id}); Bugzilla->user->can_edit_product($bug->product_id) || ThrowUserError( "product_edit_denied" , {product => $bug->product}); my $dbh = Bugzilla->dbh; my ($timestamp) = $dbh->selectrow_array( "SELECT NOW()" ); my $data = decode_base64($params->{data}); my $filename = $params->{filename}; my $description = "test from xmlrpc" ; my $contenttype = "image/jpeg" ; my $isurl = 0 ; my $isprivate = 0 ; $dbh->bz_start_transaction(); my $sth = $dbh->do( "INSERT INTO attachments (bug_id, creation_ts, modification_time, filename, description, mimetype, ispatch, isurl, isprivate, submitter_id) VALUES (?,?,?,?,?,?,?,?,?,?)", undef, ($bug->bug_id, $timestamp, $timestamp, $filename, $description, $contenttype, 0 , $isurl, $isprivate, $user->id)); # Retrieve the ID of the newly created attachment record. my $attachid = $dbh->bz_last_key( 'attachments' , 'attach_id' ); # We only use $data here in this INSERT with a placeholder, # so it's safe. $sth = $dbh->prepare("INSERT INTO attach_data (id, thedata) VALUES ($attachid, ?)"); trick_taint($data); $sth->bind_param( 1 , $data, $dbh->BLOB_TYPE); $sth->execute(); $dbh->bz_commit_transaction(); return { at => $data }; }以上就实现了怎么可以给一个现有的bug添加一个attachment了。
可能实现的不好,求高人指点更好的解法。
查看更多关于在Ruby on Rails 中用 xmlrpc 来传输附件(图片)的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://haodehen.cn/did41525