Java安全String.format和转义%

时间:2011-09-15 11:13:29

标签: java

我正在使用Java API的String.format方法来记录某些内容。我的方法就像:

public static void log(String message, Object... params){
    System.out.println(String.format(message, params));
}

但问题是,如果用户在其中的某处发送了 % 字符的消息,则会抛出异常。这是一个场景:

log("SELECT * FROM my WHERE name like '%six%'");

和Java寻找替换%s(没关系)和%'(oops)的东西。我想解决这个问题。因为没有params%s将丢失,%'会导致异常。

一个解决方案可以是message.replace("%", "%%"),但我不确定它是否是一个优雅的解决方案。

3 个答案:

答案 0 :(得分:7)

log不知道给定的%是作为格式说明符还是作为百分号。请考虑以下示例:

log("%s%s", "test");

那是"test%s""%stest"还是错误?

因此,问题必须在呼叫站点解决:

log(escape("SELECT * FROM my WHERE name like '%six%'"));

其中escape()是一个函数,您需要编写一个函数,将所有%替换为%%

或者,可以在呼叫站点使用以下内容:

log("%s", "SELECT * FROM my WHERE name like '%six%'");

答案 1 :(得分:1)

最可能滥用的简单解决方案(在%s中使用%String但不提供参数)将为您的方法提供无参数重载< em>另外到原始方法:

public static void log(String message) {
  System.out.println(message);
}

或者你可以动态地尝试检测no-params情况,但这样做的工作要多一些:

public static void log(String message, Object... params) {
  final String output;
  if (params == null || params.length = 0) {
    output = message;
  } else {
    output = String.format(message, params);
  }
  System.out.println(output);
}

答案 2 :(得分:0)

如果params的长度为0,则一个选项是将字符串直接传递给println。 另一种选择是两次重载。

public static void log(String message);
public static void log(String format, String param, String...params);