All Products
Search
Document Center

API Gateway:How do I encode parameter values in requests?

Last Updated:Jun 14, 2024

Background

When a client requests to access API Gateway, the parameter values in the request must be URL encoded based on the Unicode Transformation Format – 8-bit (UTF-8) standard to prevent garbled characters caused by special characters. Note that raw values must be used for signing in the query, header, and body sections, and that the parameter values in these sections must be encoded after signing.

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

1. Encode parameter values in the header section

Parameter values in the header section must be encoded in ISO-8859-1.

HttpPost post = new HttpPost(initUrl(host, path, querys));
for (Map.Entry<String, String> e : headers.entrySet()) {
	// Parameter values. Encode the values before you pass them in this section. For how to encode the values, see the following code.
	post.addHeader(e.getKey(), 	MessageDigestUtil.utf8ToIso88591(e.getValue()));
 }
/**     
* Change UTF-8 encoding to ISO-8859-1 encoding.     *     
* @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); 
       } 
}

2. Encode parameter values in the query section

If Chinese characters and special characters, such as plus signs (+), are contained in the values of query parameters, encode the values in UTF-8. The following code snippet provides an example:

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();
}

3. Encode parameter values in the body section

1. If the body is a form, refer to the following example:

UrlEncodedFormEntity formEntity = buildFormEntity(bodys);
    if (formEntity != null) {
        post.setEntity(formEntity);
    }
 /**
     * Build 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. If the body is not a form, refer to the following examples:

If the body is a string, refer to the following example:

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

If the body is a byte array, refer to the following example:

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

4. Encode parameter values in the path section

If the path section contains parameter values that use special characters, you must encode the values before passing them in the path section. Otherwise, issues occur in the signing process. If you pass encoded parameter values, the backend service receives encoded values as well. To obtain the original values, the backend service must decode the values.

	@Test
    public void testPath() throws Exception{
        // The request path.
        String host="your domain name";
        // Request path. Decode parameter values before you pass them in the path.         
        String type="中文 123";
        String pathParam= URLEncoder.encode(type,"UTF-8");
        String path = "/"+pathParam;
        Map<String, String> headers = new HashMap<String, String>();
        // (Required) Set this parameter based on the expected 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.
        Response response = Client.execute(request);
        System.out.println(JSON.toJSONString(response));
    }

5. Encode parameter values that contain emojis

If a parameter value contains an emoji, you must encode the value before proceeding to sign the request. Otherwise, the signing fails because the API Gateway system may not recognize the symbol.

If the backend service receives an encoded parameter value, it must decode the value to obtain the original value.