Вашите промени (фиксове, оптимизации) по framework-a
Докато правих подготовката за изпита се натъкнах на няколко проблема по framework-a, за които намерих лесни фиксове (или workaround-и).
Споделям ги тук удобство на колегите, които също са се сблъскали или тепърва ще се сблъскат с тях.
Първият проблем е свързан с наличието на space (" ") в пътя към Javache (напр. "C:\My Projects\javache"), като в този случай няма да успеете да вдигнете Javache ("Request Handler priority configuration file does not exist.").
Решението е просто - заменете всички "%20" с " " в SERVER_ROOT_FOLDER_PATH (javache -> WebConstants.java):
public static final String SERVER_ROOT_FOLDER_PATH =
Server
.class
.getResource("")
.toString()
.replace("file:/", "")
.replace(WEB_SERVER_PACKAGE_PATH, "")
.replace("%20", " "); // NOTE - replace %20 with " " to allow paths with spaces
Вторият проблем е донякъде свързан с първият (наличи на " " в пътя), но проявлението му е, че не може да се заредят статичните ресурси (напр. bootsrap.min.css).
Решението на този проблем е в toyote -> ResourceHandler.java:
private void handleResourceRequest(String resourcesFolder, String resourceName, HttpResponse response) {
try {
// Path resourcePath = Paths.get(new URL("file:/" + new File(resourcesFolder + File.separator + resourceName).getCanonicalPath()).toURI());
Path resourcePath = Paths.get(resourcesFolder + File.separator + resourceName); // NOTE - fixed loading of static resources (like CSS files) when path contains spaces
Третият проблем е краш при събмитване на форма с празно поле (напр. login с празно име или парола) в резултат на който не получаваме response (This page isn’t working + localhost didn’t send any data. + ERR_EMPTY_RESPONSE).
Причината за краша е, че такива полета пристигат като name= и при сплит по "=" в initBodyParameters получаваме масив само с един елемент (name), а се опитваме да достъпим 2 елемента.
Решението е в javache -> HttpRequestImpl.java (initBodyParameters), като в тази ситуация слагаме "" за value:
private void initBodyParameters(String requestContent) {
if (this.getMethod().equals("POST")) {
this.bodyParameters = new HashMap<>();
List<String> requestParams = Arrays.asList(requestContent.split("\\r\\n"));
if (requestParams.size() > this.headers.size() + 2) {
List<String> bodyParams = Arrays.asList(requestParams.get(this.headers.size() + 2).split("&"));
for (int i = 0; i < bodyParams.size(); i++) {
String[] bodyKeyValuePair = bodyParams.get(i).split("=");
// NOTE: Fixed crash on empty parameters from input form (ex. "username=")
if (bodyKeyValuePair.length == 2) {
this.addBodyParameter(bodyKeyValuePair[0], bodyKeyValuePair[1]);
} else if (bodyKeyValuePair.length == 1) {
this.addBodyParameter(bodyKeyValuePair[0], "");
}
}
}
}
}
Накрая ще споделя и една малка оптимизация в процеса на тестване на app-a.
Може да пренасочите artifact-a да се създава директно в javache\target\classes\webapps папката, като по този начин си спестявате ръчното копиране на ROOT.jar файла при всяка промяна в app-a.