【Java】パーセントエンコーディングをJavaで自作する

■ はじめに

https://blogs.yahoo.co.jp/dk521123/37109157.html
で、標準のjava.net.URLEncoder.encode() を試したが、以下のAPI
https://docs.oracle.com/javase/jp/8/docs/api/java/net/URLEncoder.html
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 * 特殊文字の「.」、「-」、「*」、および「_」は元のまま残します。
 * 空白文字「 」はプラス記号「+」に変換されます。
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
と記載されているが、本来は、
以下のようにパーセントエンコーディング(percent-encoding)を行わなければならない。
https://iwb.jp/s/ascii-url-encode-decode-list-and-convert-tool/
http://www.asahi-net.or.jp/~ax2s-kmtn/ref/uric.html
`#`記号エンコーディング
1.%2E
2-%2D
3*%2A
4_%5F
5Space%20

実際、java.net.URLEncoder.encode()の値を、Basic認証があるプロキシ
https://blogs.yahoo.co.jp/dk521123/37045638.html
で、試したところ、上記のような変換が必要だったので、対応できるようにJavaで実装してみる

サンプル

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

public class PercentEncoder {

  private static final String ENCODE = "UTF-8";
  private static final HashMap<String, String> MAPPER = new HashMap<String, String>() {
    private static final long serialVersionUID = 1L;
    {
      put(".", "%2E");
      put("-", "%2D");
      put("*", "%2A");
      put("_", "%5F");
      put("+", "%20");
    }
  };

  public static void main(String[] args) {

    try {
      String targetValue = " !\"#$%&'()*+,-./0123456789:;<=>?@";
      String result = PercentEncoder.encode(targetValue);
      System.out.println("Result  : " + result);
      System.out.println("Expected: %20%21%22%23%24%25%26%27%28%29%2A%2B%2C%2D%2E%2F0123456789%3A%3B%3C%3D%3E%3F%40");
      
      targetValue = "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz";
      result = PercentEncoder.encode(targetValue);
      System.out.println("Result  : " + result);
      System.out.println("Expected: ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E%5F%60abcdefghijklmnopqrstuvwxyz");

      targetValue = "{|}~";
      result = PercentEncoder.encode(targetValue);
      System.out.println("Result  : " + result);
      System.out.println("Expected: %7B%7C%7D%7E");
    } catch (UnsupportedEncodingException ex) {
      ex.printStackTrace();
    }
  }

  public static String encode(String targetValue) throws UnsupportedEncodingException {
    String returnValue = URLEncoder.encode(targetValue, PercentEncoder.ENCODE);
    for(Map.Entry<String, String> map : MAPPER.entrySet()) {
      returnValue = returnValue.replace(map.getKey(), map.getValue());
    }
    return returnValue;
  }
}

出力結果

Result  : %20%21%22%23%24%25%26%27%28%29%2A%2B%2C%2D%2E%2F0123456789%3A%3B%3C%3D%3E%3F%40
Expected: %20%21%22%23%24%25%26%27%28%29%2A%2B%2C%2D%2E%2F0123456789%3A%3B%3C%3D%3E%3F%40
Result  : ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E%5F%60abcdefghijklmnopqrstuvwxyz
Expected: ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E%5F%60abcdefghijklmnopqrstuvwxyz
Result  : %7B%7C%7D%7E
Expected: %7B%7C%7D%7E


関連記事

Java】URLエンコーディング

https://blogs.yahoo.co.jp/dk521123/37109157.html

パッケージ管理コマンド ~ プロキシ経由でapt系コマンドを実行するには... ~

https://blogs.yahoo.co.jp/dk521123/37045638.html

プロキシサーバソフト [2] ~ Squid / Basic認証編 ~

https://blogs.yahoo.co.jp/dk521123/36962466.html