PL/SQL: UTL_HTTP POST with UTF8 string results in broken characters

31,342

Solution 1

You should change your code to:

UTL_HTTP.SET_BODY_CHARSET('UTF-8');
UTL_HTTP.SET_HEADER (r      =>   req,
                     name   =>   'Content-Length',
                     value  =>    LENGTHB(v_param));

UTL_HTTP.WRITE_RAW (r    => req,
                    data => UTL_RAW.CAST_TO_RAW(v_param));

LENGTHB for byte length because of UTF-8. Otherwise the calculated length will be false and you get an error on the target side (unexpected end of input or something).

Solution 2

Same goes for the response body e.g. when you're getting a response from a web service:

UTL_HTTP.SET_BODY_CHARSET(r=> resp, charset=>'UTF-8');

Place this call directly after Get_response.

Share:
31,342
Federico Elles
Author by

Federico Elles

Updated on November 16, 2021

Comments

  • Federico Elles
    Federico Elles over 2 years

    I want to send an UTF8 json string via utl_http to a node.js Server via POST. Sending the string

    ["Sant Julià de Lòria"]
    

    does arrive as

    ["Sant Juli� de L�ria"]
    

    The PL/SQL code goes like:

    FUNCTION http_post_varchar(
        p_url          VARCHAR2,
        p_request_body VARCHAR2 )
      RETURN VARCHAR2
    AS
      req   UTL_HTTP.REQ;
      resp  UTL_HTTP.RESP;
      value VARCHAR2(32767);  -- URL to post to
      v_url VARCHAR2(200) := p_url;
      -- Post Parameters
      v_param VARCHAR2(32767) := p_request_body;
      v_param_length NUMBER := length(v_param);
    BEGIN
      req := UTL_HTTP.BEGIN_REQUEST (url=> v_url, method => 'POST');
      UTL_HTTP.SET_HEADER (r      =>  req,
                           name   =>  'Content-Type',
                           value  =>  'application/json;charset=UTF-8');
      UTL_HTTP.SET_HEADER (r      =>   req,
                           name   =>   'Content-Length',
                           value  =>   v_param_length);
      UTL_HTTP.WRITE_TEXT (r      =>   req,
                           data   =>   v_param);
    
      resp := UTL_HTTP.GET_RESPONSE(req);
      LOOP
        UTL_HTTP.READ_LINE(resp, value, TRUE);    
      END LOOP;
      UTL_HTTP.END_RESPONSE(resp);
      RETURN 'OK';
    EXCEPTION
      WHEN UTL_HTTP.END_OF_BODY THEN
        UTL_HTTP.END_RESPONSE(resp);
      RETURN 'OK';
    END http_post_varchar;