Java中在使用String.format时会遇到MissingFormatArgumentException等异常,发现是针对编码后的URL进行格式化导致的。
直接上代码,比如我们要进行下面的格式化:
String url = "http://www.csdn.net/?arg1=(a,b)&arg2=%d";
String s = String.format(url, 10);
System.out.println(s);
其输出结果是没有问题的
http://www.csdn.net/?arg1=(a,b)&arg2=10
但是如果我们对上面的url进行编码,结果就会出现问题
String domain = "http://www.csdn.net/?";
String arg = "arg1=(a,b)&arg2=%d";
String url = domain + URLEncoder.encode(arg, "UTF-8");
String s = String.format(url, 10);
System.out.println(s);
这段代码会抛出异常:
Exception in thread "main" java.util.UnknownFormatConversionException: Conversion = 'D'
问题出现的原因就在于编码这一行了,打印其输出结果是这样的:
http://www.csdn.net/?arg1%3D%28a%2Cb%29%26arg2%3D%25d
程序在解析格式化标签的时候将%3D解释为一个参数标记,所以会出错。
我们再看下面这一句:
String arg = "%darg1(a)&arg2%d";
String url = URLEncoder.encode(arg, "UTF-8");
System.out.println(url);
String s = String.format(url, 10);
System.out.println(s);
其结果如下:
%25darg1%28a%29%26arg2%25d
Exception in thread "main" java.util.MissingFormatArgumentException: Format specifier '%28a'
这里是因为第一个%25d被识别成整数标记,紧接着解析后面的%28a时,由于参数列表没有更多的参数,所以解析程序认为参数不足(MissArgument)而抛出异常。