Encoding parameters in requests

更新时间:
复制 MD 格式

Incorrect encoding in API requests causes garbled text, signature verification failures, and rejected requests. This topic explains how to encode header, query, body, and path parameters correctly, and in the right order relative to request signing.

API request encoding

URL-encode parameter values in UTF-8 before sending requests to API Gateway. This prevents garbled text when parameters contain special characters or Chinese characters.

Sign before you encode. Use the original (unencoded) values of query, header, and body parameters for signature calculation. Encode the values only after signing the request.

For sample code, see https://github.com/aliyun/api-gateway-demo-sign-java.

Encoding rules by parameter type

Parameter type

Encoding scheme

When to encode

Header

ISO-8859-1

After signing

Query

UTF-8 (percent-encoding)

After signing

Form body

UTF-8 (application/x-www-form-urlencoded)

After signing

Non-form body (string)

UTF-8

After signing

Path

UTF-8 (percent-encoding)

Before signing

Safe characters and encoding format

Percent-encoding replaces each unsafe byte with % followed by two uppercase hexadecimal digits. The following characters do not require encoding:

  • Uppercase and lowercase letters: AZ, az

  • Digits: 09

  • Unreserved punctuation: -, ., _, ~

All other characters, including spaces and the plus sign (+), must be encoded. Encode spaces as %20, not +.

Example: The string Chinese 123 contains a space, which is not a safe character. After UTF-8 percent-encoding, the space becomes %20, producing Chinese%20123.

Encode header values

Encode header values in ISO-8859-1.

HttpPost post = new HttpPost(initUrl(host, path, querys));
for (Map.Entry<String, String> e : headers.entrySet()) {
	// Header value. Encode the value before passing. See the implementation below.
	post.addHeader(e.getKey(), 	MessageDigestUtil.utf8ToIso88591(e.getValue()));
 }
/**     
* Transforms UTF-8 encoding to ISO-8859-1.     *     
* @param str     
* @return     
*/    
public static String utf8ToIso88591(String str) {        
if (str == null) { 
           return str; 
}        
try {
            return new String(str.getBytes("UTF-8"), "ISO-8859-1");        } 
catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e.getMessage(), e); 
       } 
}

Encode query values

URL-encode query parameter values in UTF-8 when they contain Chinese characters, spaces, or special characters such as +. The following code builds the full request URL with encoded query values.

private static String initUrl(String host, String path, Map<String, String> querys) throws UnsupportedEncodingException {
    	StringBuilder sbUrl = new StringBuilder();
    	sbUrl.append(host);
    	if (!StringUtils.isBlank(path)) {
    		sbUrl.append(path);
        }
    	if (null != querys) {
    		StringBuilder sbQuery = new StringBuilder();
        	for (Map.Entry<String, String> query : querys.entrySet()) {
        		if (0 < sbQuery.length()) {
        			sbQuery.append("&");
        		}
        		if (StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue())) {
        			sbQuery.append(query.getValue());
                }
        		if (!StringUtils.isBlank(query.getKey())) {
        			sbQuery.append(query.getKey());
        			if (!StringUtils.isBlank(query.getValue())) {
        				sbQuery.append("=");
        				sbQuery.append(URLEncoder.encode(query.getValue(), "UTF-8"));
        			}        			
                }
        	}
        	if (0 < sbQuery.length()) {
        		sbUrl.append("?").append(sbQuery);
        	}
        }
    	return sbUrl.toString();
}

Encode body parameters

  1. Form body encoding:

    UrlEncodedFormEntity formEntity = buildFormEntity(bodys);
        if (formEntity != null) {
            post.setEntity(formEntity);
        }
     /**
         * Builds a FormEntity.
         * 
         * @param formParam
         * @return
         * @throws UnsupportedEncodingException
         */
        private static UrlEncodedFormEntity buildFormEntity(Map<String, String> formParam)
                throws UnsupportedEncodingException {
            if (formParam != null) {
                List<NameValuePair> nameValuePairList = new ArrayList<NameValuePair>();
                for (String key : formParam.keySet()) {
                    nameValuePairList.add(new BasicNameValuePair(key, formParam.get(key)));
                }
                UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairList, "UTF-8");
                formEntity.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
                return formEntity;
            }
            return null;
        }
  2. Non-form body encoding:

For a string body:

if (StringUtils.isNotBlank(body)) {
    post.setEntity(new StringEntity(body, "UTF-8"));
}

For a byte[] body:

if (bodys != null) {
    post.setEntity(new ByteArrayEntity(bodys));
}

Encode path parameters

URL-encode path parameters in UTF-8 before adding them to the path. Unencoded special characters in path parameters cause signature calculation to fail. The backend receives the encoded value — decode it on the backend to retrieve the original.

	@Test
    public void testPath() throws Exception{
        // Request path
        String host="your domain name";
        // Request path. Process the parameter before adding it to the path.        
        String type="Chinese 123";
        String pathParam= URLEncoder.encode(type,"UTF-8");
        String path = "/"+pathParam;
        Map<String, String> headers = new HashMap<String, String>();
        // (Required) Set this based on the expected content type of the response.
        headers.put(HttpHeader.HTTP_HEADER_ACCEPT, "application/json");
        CUSTOM_HEADERS_TO_SIGN_PREFIX.clear();
        Request request = new Request(Method.GET, host, path, AppKey, AppSecret, Constants.DEFAULT_TIMEOUT);
        request.setHeaders(headers);
        request.setSignHeaderPrefixList(CUSTOM_HEADERS_TO_SIGN_PREFIX);
        // Call the server-side.
        Response response = Client.execute(request);
        System.out.println(JSON.toJSONString(response));
    }

Handle parameters that contain emojis

URL-encode parameter values that contain emojis before signing the request. API Gateway may not recognize raw emoji bytes, which causes the signature to fail.

Why this happens: Emojis are encoded as multi-byte sequences in UTF-8 (typically 4 bytes). API Gateway processes the raw bytes during signature verification and may not handle these sequences correctly, resulting in a mismatch between the computed and expected signatures.

Workaround: Percent-encode the emoji value before passing it as a parameter. The backend receives the percent-encoded string — decode it to retrieve the original emoji.