|
// Java Middleware Pattern (Lambda-Based) |
|
// Inspired by web frameworks like Express.js, this pattern demonstrates |
|
// how to chain middleware in Java using functional interfaces and lambdas. |
|
|
|
package middleware; |
|
|
|
class Request { |
|
private final String message; |
|
|
|
Request(String message) { |
|
this.message = message; |
|
} |
|
|
|
String getMessage() { |
|
return message; |
|
} |
|
|
|
@Override |
|
public String toString() { |
|
return message; |
|
} |
|
} |
|
|
|
class Response { |
|
private final String message; |
|
|
|
Response(String message) { |
|
this.message = message; |
|
} |
|
|
|
String getMessage() { |
|
return message; |
|
} |
|
|
|
@Override |
|
public String toString() { |
|
return message; |
|
} |
|
} |
|
|
|
@FunctionalInterface |
|
interface Controller { |
|
Response fetch(Request req); |
|
} |
|
|
|
@FunctionalInterface |
|
interface Middleware { |
|
Response fetch(Request req, Controller next); |
|
} |
|
|
|
class MainController implements Controller { |
|
// The core (innermost) controller β called last in the chain. |
|
// By default, it just echoes the request message as the response. |
|
private Controller outermost = req -> new Response(req.getMessage()); |
|
|
|
public MainController use(Middleware middleware) { |
|
Controller previous = outermost; |
|
outermost = req -> middleware.fetch(req, previous); |
|
return this; |
|
} |
|
|
|
@Override |
|
public Response fetch(Request req) { |
|
return outermost.fetch(req); |
|
} |
|
} |
|
|
|
class MiddlewareGroup implements Middleware { |
|
private Middleware outermost = (req, next) -> next.fetch(req); |
|
|
|
public MiddlewareGroup use(Middleware middleware) { |
|
Middleware previous = outermost; |
|
outermost = (req, next) -> |
|
middleware.fetch(req, r -> previous.fetch(r, next)); |
|
return this; |
|
} |
|
|
|
@Override |
|
public Response fetch(Request req, Controller next) { |
|
return outermost.fetch(req, next); |
|
} |
|
} |
|
|
|
class Example { |
|
public static void main(String[] args) { |
|
// Basic echo |
|
System.out.println( |
|
new MainController() |
|
.fetch(new Request("Hello world!")) |
|
); |
|
// Output: Hello world! |
|
|
|
// Modify the response |
|
System.out.println( |
|
new MainController() |
|
.use((req, next) -> new Response("BEFORE " + next.fetch(req).getMessage())) |
|
.use((req, next) -> new Response(next.fetch(req).getMessage() + " AFTER")) |
|
.fetch(new Request("Hello world!")) |
|
); |
|
// Output: BEFORE Hello world! AFTER |
|
|
|
// Modify the request |
|
System.out.println( |
|
new MainController() |
|
.use((req, next) -> next.fetch(new Request("BEFORE " + req.getMessage()))) |
|
.use((req, next) -> next.fetch(new Request(req.getMessage() + " AFTER"))) |
|
.fetch(new Request("Hello world!")) |
|
); |
|
// Output: BEFORE Hello world! AFTER |
|
|
|
// Log the request/response |
|
System.out.println( |
|
new MainController() |
|
.use((req, next) -> { |
|
System.out.println("Requesting: " + req); |
|
Response res = next.fetch(req); |
|
System.out.println("Responding with: " + res); |
|
return res; |
|
}) |
|
.fetch(new Request("Hello world!")) |
|
); |
|
// Logs and Output: |
|
// Requesting: Hello world! |
|
// Responding with: Hello world! |
|
// Hello world! |
|
|
|
// Use a group of middleware |
|
System.out.println( |
|
new MainController() |
|
.use(new MiddlewareGroup() |
|
.use((req, next) -> new Response("BEFORE " + next.fetch(req).getMessage())) |
|
.use((req, next) -> new Response(next.fetch(req).getMessage() + " AFTER"))) |
|
.fetch(new Request("Hello world!")) |
|
); |
|
// Output: BEFORE Hello world! AFTER |
|
} |
|
} |