Я реализую сопоставление шаблона URL-адреса сервлета в соответствии со спецификацией сервлета. Мой метод сопоставления:
public static boolean match(String pattern, String str, boolean isCaseSensitive) {
char[] patArr = pattern.toCharArray();
char[] strArr = str.toCharArray();
int patIdxStart = 0;
int patIdxEnd = patArr.length - 1;
int strIdxStart = 0;
int strIdxEnd = strArr.length - 1;
boolean containsStar = false;
for (int i = 0; i < patArr.length; i++) {
if (patArr[i] != '*') {
continue;
}
containsStar = true;
break;
}
if (!containsStar) {
if (patIdxEnd != strIdxEnd) {
return false;
}
for (int i = 0; i <= patIdxEnd; i++) {
char ch = patArr[i];
if (ch == '?')
continue;
if ((isCaseSensitive) && (ch != strArr[i])) {
return false;
}
if ((!isCaseSensitive)
&& (Character.toUpperCase(ch) != Character
.toUpperCase(strArr[i]))) {
return false;
}
}
return true;
}
if (patIdxEnd == 0) {
return true;
}
char ch;
while (((ch = patArr[patIdxStart]) != '*')
&& (strIdxStart <= strIdxEnd)) {
if (ch != '?') {
if ((isCaseSensitive) && (ch != strArr[strIdxStart])) {
return false;
}
if ((!isCaseSensitive)
&& (Character.toUpperCase(ch) != Character
.toUpperCase(strArr[strIdxStart]))) {
return false;
}
}
patIdxStart++;
strIdxStart++;
}
if (strIdxStart > strIdxEnd) {
for (int i = patIdxStart; i <= patIdxEnd; i++) {
if (patArr[i] != '*') {
return false;
}
}
return true;
}
while (((ch = patArr[patIdxEnd]) != '*') && (strIdxStart <= strIdxEnd)) {
if (ch != '?') {
if ((isCaseSensitive) && (ch != strArr[strIdxEnd])) {
return false;
}
if ((!isCaseSensitive)
&& (Character.toUpperCase(ch) != Character
.toUpperCase(strArr[strIdxEnd]))) {
return false;
}
}
patIdxEnd--;
strIdxEnd--;
}
if (strIdxStart > strIdxEnd) {
for (int i = patIdxStart; i <= patIdxEnd; i++) {
if (patArr[i] != '*') {
return false;
}
}
return true;
}
while ((patIdxStart != patIdxEnd) && (strIdxStart <= strIdxEnd)) {
int patIdxTmp = -1;
for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
if (patArr[i] != '*') {
continue;
}
patIdxTmp = i;
break;
}
if (patIdxTmp == patIdxStart + 1) {
patIdxStart++;
continue;
}
int patLength = patIdxTmp - patIdxStart - 1;
int strLength = strIdxEnd - strIdxStart + 1;
int foundIdx = -1;
for (int i = 0; i <= strLength - patLength; i++) {
int j = 0;
while (true)
if (j < patLength) {
ch = patArr[(patIdxStart + j + 1)];
if (ch != '?') {
if ((isCaseSensitive)
&& (ch != strArr[(strIdxStart + i + j)])) {
break;
}
if ((!isCaseSensitive)
&& (Character.toUpperCase(ch) != Character
.toUpperCase(strArr[(strIdxStart
+ i + j)])))
break;
} else {
j++;
continue;
}
} else {
foundIdx = strIdxStart + i;
break;
}
}
if (foundIdx == -1) {
return false;
}
patIdxStart = patIdxTmp;
strIdxStart = foundIdx + patLength;
}
for (int i = patIdxStart; i <= patIdxEnd; i++) {
if (patArr[i] != '*') {
return false;
}
}
return true;
}
Но когда я тестирую случай ниже:
String pattern = "*.a*";
String path = "/index.abc";
String matches = match(pattern, path, true) ? "matches" : "unmatches";
System.out.println(path + " " + matches + " " + pattern);
Тестовый пример работает вечно и не может остановиться. У меня есть 2 вопроса:
- Является ли шаблон
"*.a*"
допустимым со спецификацией сопоставления шаблона URL-адреса сервлета? - Как исправить эту ошибку, чтобы разорвать бесконечный цикл?