#ruby-on-rails #soap #ruby-on-rails-4 #multipart #savon
#ruby-on-rails #soap #ruby-on-rails-4 #многостраничный #savon
Вопрос:
Требование: ответ «transaction_id» из API и при загрузке параметров нам также требуется передать PDF-файл вместе с этим API, но нет параметра для отправки файла с API.Итак, мы делаем это в нашей модели как multipart / form-data для http-запроса.
http://xyz.xyz.com/xyz/upload.ashx?u=usernameamp;p=passwordtid=ticketGuid
Имя пользователя «xxxxxxx» Пароль «гггг» tid «f155a1e5-d1cd-4edb-8d25-89f3852a06f4»
Требуется ответ TransID (десятичный)
Наш код модели приведен ниже,
требуется «net / http»
задание класса < ActiveRecord::Base after_update:upload_ticket_file
has_attached_file :ad_pdf
validates_attachment_content_type :ad_pdf, :content_type => "application/pdf"
validates_attachment :ad_pdf, :presence => true
validates :section_id, :section, :colour_id, :colour, :size_id, :sizes, :height, :width, :height_bleed, :width_bleed, :booking_number, :presence => true
def generate_xml_ticket
"<?xml version='1.0' encoding='UTF-8'?><env:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ads='http://adstream.com/' xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'><env:Body><ads:AddTicketToPool><ads:XMLTicket><![CDATA[<?xml version='1.0' encoding='utf-8'?><jobbag><jobentry><colour_name /><page_setup><bleed_depth>#{(self.height_bleed.to_f*2.83).round(2)}</bleed_depth><bleed_width>#{(self.width_bleed.to_f*2.83).round(2)}</bleed_width><trim_depth>#{(self.height.to_f*2.83).round(2)}</trim_depth><trim_width>#{(self.width.to_f*2.83).round(2)}</trim_width></page_setup><named_size>#{self.sizes.split('/').last}</named_size><number_of_columns>#{self.size_number_of_columns}</number_of_columns><publication_code>#{self.publication_code}</publication_code><publisher_code>#{PUBLISHER[:code]}</publisher_code><section_code>#{self.section.split('/')[1]}</section_code><style>3</style><attention/><instructions /><booking_number pscode='BkNo' psformat='pZ1F' pstitle='Booking #' pstype='1'>#{self.booking_number}</booking_number><publication_date pscode='RnDt' psformat='yZ00' pstitle='Publicaiton Date' pstype='1'>#{self.issue_date.strftime("%d-%b-%Y")}</publication_date><caption /><insertion_number/><production_key /><customer_name pscode='ACNm' psformat='sZ00' pstitle='Ad Client Name' pstype='1'>#{PUBLISHER[:company_name].to_s}</customer_name><any pscode='APro' psformat='NZ00' pstitle='Brand' pstype='1'>#{self.brand}</any><any pscode='Camp' psformat='nZ00' pstitle='Campaign' pstype='1'>#{self.campaign}</any><any pscode='Rpla' psformat='bP00' pstitle='Replacement Material' pstype='1'>false</any><any pscode='Hard' psformat='BP00' pstitle='Hard Proof Sent' pstype='1'>false</any></jobentry><job_common><operator>#{self.attention_to}</operator><file_name>#{self.ad_pdf_file_name}</file_name></job_common></jobbag>]]></ads:XMLTicket></ads:AddTicketToPool></env:Body></env:Envelope>"
end
def upload_ticket_file
# response = system("curl -v -F media=@#{self.ad_pdf.path} -F message='#{self.ad_pdf_file_name}' '#{ADSTREAM_QPWEB_UPLOAD_URL}?u=#{ADSTREAM_QPWEB_USERNAME}amp;p=#{ADSTREAM_QPWEB_PASSWORD}amp;tid=#{self.ticket_guid}'"
# uri = URI.parse(ADSTREAM_QPWEB_UPLOAD_URL "?u=#{ADSTREAM_QPWEB_USERNAME_ENCODED}amp;p=#{ADSTREAM_QPWEB_PASSWORD}amp;tid=#{self.ticket_guid}")
boundary = "ABASDASDSAKJDFKDFNDKFDKFJDKNDFDN"
uri = URI.parse(ADSTREAM_QPWEB_UPLOAD_URL "?u=#{ADSTREAM_QPWEB_USERNAME_ENCODED}amp;p=#{ADSTREAM_QPWEB_PASSWORD}amp;tid=#{self.ticket_guid}")
puts ">>>>>>>>>>>>>>>>>>>>>>>>>"
puts ADSTREAM_QPWEB_UPLOAD_URL "?u=#{ADSTREAM_QPWEB_USERNAME_ENCODED}amp;p=#{ADSTREAM_QPWEB_PASSWORD}amp;tid=#{self.ticket_guid}"
file = self.ad_pdf.path
post_body = []
post_body << "Content-Disposition: form-data; name='datafile'; filename='#{self.ad_pdf_file_name}'"
post_body << "Content-Type: application/pdf"
post_body << File.read(file) boundary
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri)
request.body = post_body.join
request["Content-Type"] = "multipart/form-data"
request.add_field('session', boundary)
response = http.request(request)
puts request.inspect
puts response.inspect
if response and (response.body != "ticketnotaddedtostore" and !response.body.to_s.blank? and response.body != "incorrectquerystrings")
if self.update_attribute(:transaction_id, response.body)
client = Savon.client(namespace_identifier: :ads) do
wsdl ADSTREAM_QPWEB_URL
log true
end
message = {TransID: self.transaction_id}
response = client.call(:check_status) do
message (message)
end
self.update_attribute(:check_status_result, response.body.to_hash[:check_status_response][:check_status_result])
end
end
end
конец
класс JobXMLTicket
def to_s
builder = Builder::XmlMarkup.new
builder.instruct!(:xml, encoding: "UTF-8")
builder.jobbag { |jo|
jo.jobentry { |je|
je.colour_name
je.page_setup {|ps|
ps.bleed_depth "0.0"
ps.bleed_width "0.0"
ps.trim_depth "725.66"
ps.trim_width "1150.86"
}
}
}
builder
end
конец
Ответ №1:
Используя ‘RestClient gem’, мы можем сделать необходимое
require "net/http"
require 'savon'
require 'rest_client'
$config = {
qpweb_upload_url: 'http://example.com/WebAPI/upload.ashx'
}
class Job < ActiveRecord::Base
def uploadPdf
q = URI.encode_www_form( {
:u => USERNAME,
:p => PASSWORD,
:tid => ticket_guid
})
response = RestClient.post( $config[:qpweb_upload_url] '?' q, :file =>File.open(self.ad_pdf.path, 'rb') )
id = /transid=(.*)/.match( response.to_str )
raise 'error uploading file' if !id
puts 'TransactionId: ', id[1]
return id[1]
end
end