我们可以替换 Java 中开头和结尾有符号的字符串的一部分来识别吗?
Can we Replace a portion of String in Java which has symbol in the start and end to Identify?
我有一个字符串 SELECT *FROM USERS WHERE ID = '@userid@' AND ROLE = '@role@'
现在我已经用实际值替换了@...@ 之间的任何字符串。
预期输出SELECT *FROM USERS WHERE ID = '4' AND ROLE = 'Admin'
这个替换将从一个方法中发生,我已经写了这个逻辑
public String replaceQueryKeyWithValueFromKeyValues(String query, int reportId) {
try {
REPMReportDao repmReportDao = new REPMReportDao();
int Start = 0;
int end;
if (query.contains("@")) {
boolean specialSymbolFound = false;
for (int i = 0; i < query.length(); i++) {
if (query.charAt(i) == '@') {
if (!specialSymbolFound) {
Start = i + 1;
specialSymbolFound = true;
} else {
specialSymbolFound = false;
end = i;
query = query.replace(query.substring(Start - 1, end + 1), repmReportDao.getReportManagerKeyValue(query.substring(Start - 1, end + 1).replaceAll("@", ""), reportId));
}
}
}
return query;
} else {
return query;
}
} catch (Exception e) {
logger.log(Priority.ERROR, e.getMessage());
return e.getMessage();
}
}
它工作正常,但如果存在单个“@”符号而不是开始和结束,它将失败。 喜欢:
SELECT *FROM USERS WHERE emailid = 'xyz@gmail.com' AND ROLE = '@role@'
在这里它应该替换唯一的角色“@role@”并且应该保留电子邮件原样。
预期输出 => SELECT *FROM USERS WHERE emailid = 'xyz@gmail.com' AND ROLE = 'Admin'
使用字符串替换生成数据库查询被认为是非常 不好的做法,因为您的代码容易受到 SQL 注入攻击。我无法从您提供的小代码示例中看出,但绝大多数大型 Java 项目都使用 Spring Framework, which allows you to use either JdbcTemplate or (my preference) NamedParameterJdbcTemplate。两者都允许您以安全的方式替换变量。
包含 getReportManagerKeyValue
:
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Whosebug54842971 {
private static Map<String, String> map;
public static void main(String[] args) {
// preparing test data
map = new HashMap<>();
map.put("role", "Admin");
map.put("userid", "666");
// original query string
String query = "SELECT * FROM USERS WHERE ID = '@userid@' AND emailid = 'xyz@gmail.com' AND ROLE = '@role@' ";
// regular expression to match everything between '@ and @' with capture group
// omitting single quotes
Pattern p = Pattern.compile("'(@[^@]*@)'");
Matcher m = p.matcher(query);
while (m.find()) {
// every match will be replaced with value from getReportManagerKeyValue
query = query.replace(m.group(1), getReportManagerKeyValue(m.group(1).replaceAll("@", "")));
}
System.out.println(query);
}
// you won't need this function
private static String getReportManagerKeyValue(String key) {
System.out.println("getting key " + key);
if (!map.containsKey(key)) {
return "'null'";
}
return map.get(key);
}
}