I introduced you to Javalin, in this tutorial we will learn more about how we will handle requests in the Javalin framework!
I also created a Maven project as an example:
Javalin and SLF4J Simple dependency are as follows:
1 2 3 4 5 6 7 8 9 10 |
<dependency> <groupId>io.javalin</groupId> <artifactId>javalin</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.7.26</version> </dependency> |
I also created a class with the main() method that initializes a web server with the Javalin object as follows:
1 2 3 4 5 6 7 8 9 10 11 |
package com.huongdanjava.javalin; import io.javalin.Javalin; public class JavalinExample { public static void main(String[] args) { Javalin javalin = Javalin.create().start(8080); } } |
As I said, to handle request in Javalin, we will use its Functional Interface Handler. The Handler class only has a handle() method with a parameter of a Context object, and this Context object will keep all the request and response information for a request.
I implement the Handler object for GET request “/example” as follows:
1 2 3 4 5 6 7 |
javalin.get("/example", new Handler() { @Override public void handle(Context ctx) throws Exception { } }); |
We will use queryParam() method to get information about request parameters from the user, for example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
package com.huongdanjava.javalin; import io.javalin.Context; import io.javalin.Handler; import io.javalin.Javalin; public class JavalinExample { public static void main(String[] args) { Javalin javalin = Javalin.create().start(8080); javalin.get("/example", new Handler() { @Override public void handle(Context ctx) throws Exception { String name = ctx.queryParam("name"); ctx.result(name); } }); } } |
Result:
One of the queryParam() overload method also allows us to validate the data we pass on. The parameters of this method include the key as request parameter and the class is the data type of that parameter’s value. For example, if I now edit the above code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
package com.huongdanjava.javalin; import io.javalin.Context; import io.javalin.Handler; import io.javalin.Javalin; import io.javalin.validation.TypedValidator; public class JavalinExample { public static void main(String[] args) { Javalin javalin = Javalin.create().start(8080); javalin.get("/example", new Handler() { @Override public void handle(Context ctx) throws Exception { TypedValidator<Integer> id = ctx.queryParam("id", Integer.class); ctx.result(id.get() + ""); } }); } } |
then when you request the URL http://localhost:8080/example?id=Khanh, you will see the following error:
We can define the request with the path parameter as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
package com.huongdanjava.javalin; import io.javalin.Context; import io.javalin.Handler; import io.javalin.Javalin; public class JavalinExample { public static void main(String[] args) { Javalin javalin = Javalin.create().start(8080); javalin.get("/example/:name", new Handler() { @Override public void handle(Context ctx) throws Exception { String name = ctx.pathParam("name"); ctx.result(name); } }); } } |
In the above code, I have defined a path parameter name, to get this value, we will use pathParam() method of the Context object.
Similar to the queryParam() method, we can also validate the user’s request data using pathParam() overload method.
If your request has a body part, you can use the body() method or bodyAsClass() method to get data in this body section. Examples are as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
package com.huongdanjava.javalin; import io.javalin.Context; import io.javalin.Handler; import io.javalin.Javalin; public class JavalinExample { public static void main(String[] args) { Javalin javalin = Javalin.create().start(8080); javalin.post("/example", new Handler() { @Override public void handle(Context ctx) throws Exception { String name = ctx.body(); ctx.result(name); } }); } } |
Result:
With the body part, we can validate data using the bodyValidator() method!
After validating with the queryParam(), pathParam() or bodyValidator() methods, you can also add more conditions to check the data sent by the user using the check() method of TypedValidator object as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
package com.huongdanjava.javalin; import io.javalin.Context; import io.javalin.Handler; import io.javalin.Javalin; import io.javalin.validation.TypedValidator; public class JavalinExample { public static void main(String[] args) { Javalin javalin = Javalin.create().start(8080); javalin.get("/example", new Handler() { @Override public void handle(Context ctx) throws Exception { TypedValidator<Integer> id = ctx.queryParam("id", Integer.class); id.check(i -> i > 10); ctx.result(id.get() + ""); } }); } } |
Result:
Usually, when implementing RESTful Web Service applications, we often implement CRUD APIs (Create, Read, Update, Delete) and these APIs often start with the same context path, “/user” for example.
1 2 3 4 |
javalin.post("/user/", ctx -> ctx.result("")); javalin.get("/user/:id", ctx -> ctx.result("")); javalin.patch("/user/:id", ctx -> ctx.result("")); javalin.delete("/user/:id", ctx -> ctx.result("")); |
For simplicity and increased readable capability, Javalin supports groups handler so that we can group to handle the requests as follows:
1 2 3 4 5 6 7 8 9 10 |
javalin.routes(() -> { path("user", () -> { post(UserService::createUser); path(":id", () -> { get(UserService::getUser); patch(UserService::updateUser); delete(UserService::deleteUser); }); }); }); |
To use the above code, you will need to implement the Handler interface for the post(), get(), delete(), patch() methods in another class and in addition you need to import these static methods from the class io.javalin.apibuilder.ApiBuilder!
One more thing of Javalin in the handling request that you need to know is that we can use Javalin before() and after() methods to add processing before handle request and before return response for any request or all requests.
For example, if I want before handling any requests for the above example, the application will print the words “Start processing …” then I will fix the code again as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
package com.huongdanjava.javalin; import io.javalin.Context; import io.javalin.Handler; import io.javalin.Javalin; import io.javalin.validation.TypedValidator; public class JavalinExample { public static void main(String[] args) { Javalin javalin = Javalin.create().start(8080); javalin.before(ctx -> { System.out.println("Start processing..."); }); javalin.get("/example", new Handler() { @Override public void handle(Context ctx) throws Exception { TypedValidator<Integer> id = ctx.queryParam("id", Integer.class); id.check(i -> i > 10); ctx.result(id.get() + ""); } }); } } |
Result: