Sử dụng gem savon Phần II

II. Cách sử dụng
4. Locals - Tùy chọn locals được truyền cho phía client thông qua phương thức #callvà được cụ thể trong 1 request duy nhất - HTTP + soap_action
Bạn có thể cần phải cài đặt này nếu bạn không có một WSDL. Nếu bạn không có Savon nên đặt tiêu đề SOAPAction HTTP thích hợp cho bạn. Bạn không muốn Savon tự làm, hãy mở một vấn đề và thêm WSDL của dịch vụ.

            client.call(:authenticate, soap_action: "urn:Authenticate")
    + cookies <br>
    Savon 2.0 cố gắng để tự động xử lý các `cookie` bằng cách lưu trữ các tập tin cookie từ các `response` và sử dụng chúng cho các yêu cầu tiếp theo. Điều này là sai và nó gây ra vấn đề. Savon 2.1 không đặt `Cookie` vào `header`cho bạn, nhưng nó làm cho dễ dàng cho bạn để xử lý `cookie` của mình.
        response     = client.call(:authenticate, message: credentials)
        auth_cookies = response.http.cookies
        client.call(:find_user, message: { id: 3 }, cookies: auth_cookies)
    Tùy chọn này chấp nhận một mảng của đối tượng `HTTPI::Cookie` hoặc bất kỳ đối tượng mà đáp ứng `cookie` (ví dụ, một `HTTPI :: Response`).
- Request
    + message <br>
    Bạn có thể thêm một số đối số yêu cầu của bạn. Đối với `XML` bạn có thể  khai báo đơn giản như một Hash, bạn có thể truyền vào các thông điệp SOAP là một Hash. Savon sử dụng Gyoku dịch Hash vào XML.
            client.call(:authenticate, message: { username: "user_name", password: "secretpassword" })
    Đối với các cấu trúc XML phức tạp hơn, bạn có thể truyền bất kỳ đối tượng mà không phải là một Hash và đáp ứng `#test` nếu bạn muốn sử dụng một công cụ cụ thể hơn để xây dựng yêu cầu của bạn.
            def test
                builder = Builder::XmlMarkup.new
                builder.instruct!(:xml, encoding: "UTF-8")

                builder.person { |b|
                  b.username("user_name")
                  b.password("password")
                }

                builder
            end
    <br>
            client.call(:authenticate, message: test)
    + message_tag <br>
    Bạn có thể thay đổi tên `message_tag` trong SOAP. Nếu bạn cần phải sử dụng tùy chọn này
            client.call(:authenticate, message_tag: :authenticationRequest)
    Điều này nên được thiết lập bởi Savon nếu nó có một WSDL. Nếu không, nó sẽ tự tạo ra `message_tag` từ SOAP. Đây là cách các tùy chọn thay đổi theo yêu cầu.
            <env:Envelope
                xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
                xmlns:tns="http://v1.example.com/">
              <env:Body>
                <tns:authenticationRequest>
                </tns:authenticationRequest>
              </env:Body>
            </env:Envelope>
    + attributes <br>
    `message_tag` chấp nhận thuộc tính tùy chọn của `Hash` hoặc thẻ `XML`.
            client.call(:authenticate, :attributes => { "id" => "1234" })
    `Request` của SOAP sẽ như sau:
            <env:Envelope
                xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
                xmlns:tns="http://v1.example.com/">
              <env:Body>
                <tns:authenticationRequest id="1234">
                </tns:authenticationRequest>
              </env:Body>
            </env:Envelope>
    + soap_header <br>
    Kể từ v2.3.0 bạn có thể chỉ định các `soap_header` cho mỗi request. Khi cả hai tùy chọn `globals` và `locals` được sử dụng, Savon sẽ hợp nhất `globals` với `locals` Hash.
            client.call(:authenticate, :soap_header => { "access_token" => "secret_token" })
    + xml <br>
    Nếu cần bạn có thể  gửi 1 `shortcut` `XML` SOAP có thể gửi thông điệp cho bạn.
        client.call(:authenticate, xml: "<envelope>....</envelope>")
- Errors
    + Savon::Error <br>
    Là lớp cơ sở cho tất cả các lỗi của Savon. Điều này cho phép bạn hoặc là bắt lỗi `Savon::SOAPFault` hoặc là thoát khỏi lỗi đang xảy ra `Savon::Error`
    + Savon::SOAPFault <br>
    Thông báo lỗi khi SOAP phát hiện lỗi xảy ra. Các đối tượng lỗi được chứa trong `HTTPI`, bạn có thể tiếp tục kiểm tra nguyên nhân của lỗi xảy ra
            def authenticate
              client.call(:authenticate, message: {user_name: "user_name", password: "password"})
            rescue Savon::SOAPFault => error
              Logger.log error.http.code
              raise
            end
    Ví dụ trên cho phép thoát khỏi cái lỗi của SOAP, ghi lại log mã lỗi của SOAP. Ta cũng có thể dịch lại các mã lỗi của SOAP
            def authenticate
              client.call(:authenticate, message: {user_name: "user_name", password: "password"})
            rescue Savon::SOAPFault => error
              test = error.to_hash[:fault][:faultcode]
              raise test
            end
    + Savon::HTTPError <br>
    Lỗi được thông báo trong kết quả trả về của `HTTP`. Ta có thể bỏ qua lỗi này và kiểm tra lỗi xảy ra.
            def authenticate
              client.call(:authenticate, message: {user_name: "user_name", password: "password"})
            rescue Savon::HTTPError => error
              Logger.log error.http.code
              raise
            end
    + Savon::InvalidResponseError <br>
    Khi ta cố gắng truy cập vào các `hearder` hoặc `body` của response mà không phải là SOAP response như 1 Hash thì sẽ thông báo lỗi. Nếu response không phải là `XML`, `header` và `body` không thể truy cập được như một Hash!
            def get_city response
              response.body[:city_id]
            rescue Savon::InvalidResponseError
              Logger.log "Invalid City Id"
              raise
            end
- Response
`Response` cung cấp một vài phương thức để ta làm việc với `XML` một cách dễ dàng.
    + `header` <br>
    Dịch `response` và trả về SOAP `header` như một Hash.
            response.header
    + `body`<br>
    Dịch `response` và trả về SOAP `body` như một Hash
            response.body
    + `hash` <br>
    Dịch `response` và trả về SOAP là một Hash
            response.hash
    + `to_xml` <br>
    Trả về dữ liệu SOAP
            response.to_xml
    + `doc` <br>
    Trả về dữ liệu là một `Nokogiri`
    + `http` <br>
    Trả về  HTTPI response.
            response.http
    Trong trường hợp bạn vô hiệu hóa tùy chọn: `raise_errors`, bạn có thể sử dụng phương thức kiểm tra trạng thái của nó.
        response.success?
        response.soap_fault?
        response.http_error?
- Model