Java webserver implementation mostly without any external dependencies (only jetbrains annotations).
- HTTP/2
- GET, POST, HEAD, PUT, DELETE, OPTIONS, TRACE, CONNECT
- Middlewares
- Routes
- Static files serving
- Reflection routers parsing (define page with using method annotation)
- Cookies
- Websockets
- Chunked transfer encoding
- GZIP compression
- Basic authentication
- Sessions
- Logging
- Error pages
repositories {
mavenCentral()
maven {
url = "https://repo.redguy.ru/repository/maven-public/"
}
}
dependencies {
implementation("ru.redguy:jrweb:$version") {
capabilities {
requireCapability("ru.redguy:jrweb-brotli-support:$version")
}
}
}
To enable brotli compression you need to enable feature brotliSupport.
implementation("ru.redguy:jrweb:$version") {
capabilities {
requireCapability("ru.redguy:jrweb-brotli-support:$version")
}
}
class Main {
public static void main(String[] args) {
WebServer server = new WebServer();
server.start(80);
server.addPage(new Page("/", (ctx) -> {
ctx.response.setStatusCode(StatusCodes.OK);
ctx.response.send("<html><body>Hello World!</body></html>");
}));
}
}
server.addPage(new Page("/redirect",(ctx) -> {
ctx.response.setStatusCode(StatusCodes.MOVED_PERMANENTLY("https://google.com"));
}));
server.addPage(new Page(Methods.POST,"/post-only",(ctx) -> {
ctx.response.setStatusCode(StatusCodes.OK);
ctx.response.send("<html><body>POST ONLY</body></html>");
}));
Router router = server.addRouter(new Router("/route"));
router.add(new Page("/test",(ctx) -> {
ctx.response.setStatusCode(StatusCodes.OK);
ctx.response.send("<html><body>Route test</body></html>");
}));
server.addPage(new Page(Methods.GET, "/file", (ctx) -> {
ctx.response.setStatusCode(StatusCodes.OK);
InputStream is = SimpleWebServer.class.getResourceAsStream("rick.webp");
byte[] bytes = readAllBytes(is);
ctx.response.getHeaders().add(Headers.Response.CONTENT_LENGTH, String.valueOf(bytes.length));
ctx.response.send(bytes);
}));
server.addRouter(new FileRouter("/src", Paths.get("src")));
server.addRouter(new RouterClass());
@Router("/class")
public class RouterClass {
@Page("/call")
public void call(@NotNull Context context) {
context.response.send("Hello from RouterClass");
}
}
server.addRouter(new ResourcesRouter("/resources", "/"));
server.addPage(new Page("/headers",(ctx) -> {
ctx.response.send("<html><body>Headers:<br>");
ctx.request.headers.forEach((e) -> {
ctx.response.send(e.generate() + ": " + e.getValue() + "<br>");
});
ctx.response.send("</body></html>");
}));
server.addPage(new Page("/ws", new WebSocket() {
@Override
public void onMessage(Context ctx, DataFrame frame) {
try {
send(ctx, frame.getPayloadText());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}));
MIT
RedGuys