您的位置:首页 > 编程语言 > Ruby

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

2012-01-24 13:49 471 查看

/article/3914761.html

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

博客分类:ruby on rails
RailsRubyWebServiceMySQLCGI还是上次的需求,让做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

end
3.在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了。

可能实现的不好,求高人指点更好的解法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: