code: public static String encodeQueryParam(String queryParam, boolean relax) {
          boolean[] unreserved = queryParamChars;
          String string = queryParam;
  
          if (queryParam == null) {
              return null;
          }
  
          if (!needsEncoding(queryParam, false, unreserved)) {
              return string;
          }
  
          // Encode to UTF-8
          ByteBuffer buffer = CHARSET_UTF_8.encode(string);
          // Prepare string buffer
          StringBuilder sb = new StringBuilder(buffer.remaining());
          // Now encode the characters
          while (buffer.hasRemaining()) {
              int c = buffer.get();
  
              if ((c == '%') && relax && (buffer.remaining() >= 2)) {
                  int position = buffer.position();
                  if (isHex(buffer.get(position)) && isHex(buffer.get(position + 1))) {
                      sb.append((char)c);
                      continue;
                  }
              }
  
              if ((c >= ' ' && unreserved[c])) {
                  sb.append((char)c);
              } else if ((c == ' ')) {
                  sb.append('+');
              } else {
                  sb.append('%');
                  sb.append(hexDigits[(c & 0xf0) >> 4]);
                  sb.append(hexDigits[c & 0xf]);
              }
          }
  
          return sb.toString();
      }
docs: Encode a query parameter (name or value) according to <a
  href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>.
  
  @param queryParam the query parameter string to encode
  @param relax if true, then any sequence of chars in the input string that
  have the form '%XX', where XX are two HEX digits, will not be
  encoded
  @return encoded query parameter string