See the documentation page for up-to-date information.
Custom JSON mapper
Context#json
used to rely on Jackson to do JSON mapping. As of 1.7.0
it relies on JavalinJsonPlugin
.
This plugin holds a default implementation for Jackson, but can be configured to use whatever you like.
This is how to use GSON instead of Jackson:
Gson gson = new GsonBuilder().create();
JavalinJsonPlugin.setJsonToObjectMapper(gson::fromJson);
JavalinJsonPlugin.setObjectToJsonMapper(gson::toJson);
jTwig templates
jTwig is the Java implementation of a very popular PHP template engine.
This can now be used via Context#renderJtwig
.
Miscellaneous
Javalin
’s constructor is nowprotected
instead ofprivate
. This means you can subclassJavalin
.Javalin
now hasdisableStartupBanner()
, which removes the Javalin banner from logsJavalin
will now print more helpful error messages if the current port can’t be used.
Context extensions
Context extensions give Java developers a way of extending the Context
object.
One of the most popular features of Kotlin is extension functions.
When working with an object you don’t own in Java, you often end up making MyUtil.action(object, ...)
.
If you, for example, want to serialize an object and set it as the result on the Context
, you might do:
app.get("/", ctx -> MyMapperUtil.serialize(ctx, myMapper, myObject)); // three args, what happens where?
With context extensions you can add custom extensions on the context:
app.get("/", ctx -> ctx.use(MyMapper.class).serialize(object)); // use MyMapper to serialize object
Context extensions have to be added before you can use them, this would typically be done in the first before
filter of your app:
app.before(ctx -> ctx.register(MyMapper.class, new MyMapper(ctx, otherDependency));
You could also create a general extension class which holds all your extensions:
VelocityEngine velocityEngine = new VelocityEngine();
Gson gson = new GsonBuilder().create();
app.before(ctx -> ctx.register(Ext.class, new Ext(ctx, gson, velocityEngine)));
Extensions are very powerful, you can use them for any action performed on the Context
.
Another example is parameter extraction:
public class Ext {
private Context ctx;
public Ext(Context ctx) {
this.ctx = ctx;
}
public String formUsername() {
String username = ctx.formParam("username");
if (userName == null) {
throw new InvalidFormException();
}
return username;
}
public String userLocale() {
return ctx.queryParam("locale");
}
}
app.post(ctx -> {
String username = ctx.use(Ext.class).formUsername();
String locale = ctx.use(Ext.class).userLocale();
});
As you see with the throw
, extensions can also complicate your application. Use them with caution.