url parser, path and query parameters

This commit is contained in:
Daniel
2024-10-23 23:17:07 +03:00
parent 4164c304a4
commit 1d5c7fbc15
6 changed files with 131 additions and 14 deletions

View File

@@ -14,4 +14,11 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>
<dependencies>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.11.0</version>
</dependency>
</dependencies>
</project> </project>

View File

@@ -19,8 +19,11 @@ public class Main {
chain.next(req, res); chain.next(req, res);
}); });
server.GET("/hello", (req, res) -> server.GET("/test/:lel/", (req, res) -> {
res.sendResponse(HttpStatus.OK, "Hello, World!")); Logger.info("PATH", req.getPathParam("lel"));
Logger.info("QUERY", req.getQueryParam("lol"));
res.sendResponse(HttpStatus.OK, "All good, lil bro");
});
server.start(); server.start();
} }

View File

@@ -1,5 +1,7 @@
package org.lumijiez.core.http; package org.lumijiez.core.http;
import org.lumijiez.core.util.UrlParser;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
@@ -10,6 +12,7 @@ public class HttpRequest {
private String path; private String path;
private String httpVersion; private String httpVersion;
private final Map<String, String> headers; private final Map<String, String> headers;
private UrlParser urlParser;
public HttpRequest(BufferedReader in) throws IOException { public HttpRequest(BufferedReader in) throws IOException {
this.headers = new HashMap<>(); this.headers = new HashMap<>();
@@ -49,6 +52,26 @@ public class HttpRequest {
"keep-alive".equalsIgnoreCase(connection); "keep-alive".equalsIgnoreCase(connection);
} }
public void setUrlParser(UrlParser urlParser) {
this.urlParser = urlParser;
}
public String getPathParam(String name) {
return urlParser != null ? urlParser.getPathParam(name) : null;
}
public String getQueryParam(String name) {
return urlParser != null ? urlParser.getQueryParam(name) : null;
}
public Map<String, String> getPathParams() {
return urlParser != null ? urlParser.getPathParams() : Map.of();
}
public Map<String, String> getQueryParams() {
return urlParser != null ? urlParser.getQueryParams() : Map.of();
}
public String getMethod() { public String getMethod() {
return method; return method;
} }

View File

@@ -3,5 +3,4 @@ package org.lumijiez.core.routing;
import org.lumijiez.core.http.HttpHandler; import org.lumijiez.core.http.HttpHandler;
import org.lumijiez.core.http.HttpMethod; import org.lumijiez.core.http.HttpMethod;
public record Route(HttpMethod method, String path, HttpHandler handler) { public record Route(HttpMethod method, String path, HttpHandler handler) { }
}

View File

@@ -3,24 +3,22 @@ package org.lumijiez.core.routing;
import org.lumijiez.core.http.*; import org.lumijiez.core.http.*;
import org.lumijiez.core.middleware.Chain; import org.lumijiez.core.middleware.Chain;
import org.lumijiez.core.middleware.Middleware; import org.lumijiez.core.middleware.Middleware;
import org.lumijiez.core.util.UrlParser;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
public class Router { public class Router {
private final Map<String, Route> routes = new HashMap<>(); private final List<Route> routes = new ArrayList<>();
private final List<Middleware> middleware = new ArrayList<>(); private final List<Middleware> middleware = new ArrayList<>();
public void addMiddleware(Middleware middleware) { public void addMiddleware(Middleware middleware) {
this.middleware.add(middleware); this.middleware.add(middleware);
} }
public void addRoute(HttpMethod method, String path, HttpHandler handler) { public void addRoute(HttpMethod method, String pattern, HttpHandler handler) {
String key = method.name() + ":" + path; routes.add(new Route(method, pattern, handler));
routes.put(key, new Route(method, path, handler));
} }
public void handleRequest(HttpRequest request, HttpResponse response) throws IOException { public void handleRequest(HttpRequest request, HttpResponse response) throws IOException {
@@ -41,11 +39,20 @@ public class Router {
} }
private void executeHandler(HttpRequest request, HttpResponse response) throws IOException { private void executeHandler(HttpRequest request, HttpResponse response) throws IOException {
String key = request.getMethod() + ":" + request.getPath(); UrlParser urlParser = new UrlParser(request.getPath());
Route route = routes.get(key); Route matchedRoute = null;
if (route != null) { for (Route route : routes) {
route.handler().handle(request, response); if (route.method().name().equals(request.getMethod()) &&
urlParser.matchesPattern(route.path())) {
matchedRoute = route;
break;
}
}
if (matchedRoute != null) {
request.setUrlParser(urlParser);
matchedRoute.handler().handle(request, response);
} else { } else {
response.sendResponse(HttpStatus.NOT_FOUND, "Not Found"); response.sendResponse(HttpStatus.NOT_FOUND, "Not Found");
} }

View File

@@ -0,0 +1,78 @@
package org.lumijiez.core.util;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class UrlParser {
private final String path;
private final Map<String, String> queryParams;
private final Map<String, String> pathParams;
public UrlParser(String rawUrl) {
this.queryParams = new HashMap<>();
this.pathParams = new HashMap<>();
String[] urlParts = rawUrl.split("\\?", 2);
this.path = urlParts[0];
if (urlParts.length > 1) {
parseQueryParams(urlParts[1]);
}
}
private void parseQueryParams(String queryString) {
String[] pairs = queryString.split("&");
for (String pair : pairs) {
String[] keyValue = pair.split("=", 2);
if (keyValue.length == 2) {
queryParams.put(keyValue[0], keyValue[1]);
} else if (keyValue.length == 1) {
queryParams.put(keyValue[0], "");
}
}
}
public boolean matchesPattern(String pattern) {
String[] patternParts = pattern.split("/");
String[] pathParts = this.path.split("/");
if (patternParts.length != pathParts.length) {
return false;
}
for (int i = 0; i < patternParts.length; i++) {
String patternPart = patternParts[i];
String pathPart = pathParts[i];
if (patternPart.startsWith(":")) {
String paramName = patternPart.substring(1);
pathParams.put(paramName, pathPart);
} else if (!patternPart.equals(pathPart)) {
return false;
}
}
return true;
}
public String getPath() {
return path;
}
public String getQueryParam(String name) {
return queryParams.get(name);
}
public String getPathParam(String name) {
return pathParams.get(name);
}
public Map<String, String> getQueryParams() {
return Collections.unmodifiableMap(queryParams);
}
public Map<String, String> getPathParams() {
return Collections.unmodifiableMap(pathParams);
}
}