0

I'm using Javalin to serve my static web pages, which I've never done before. I know it's possible in Nginx to remove the .html from the end of your url but still route to the correct page, for example mysite.com/login would replace mysite.com/login.html but still point towards my login.html file. Is this possible in Javalin?

I've tried looking into the config (StaticFileConfig) but couldn't seem to find anything that would solve this problem

jchernin4
  • 11
  • 2
  • 7
  • I would say that the static file location is not really intended to be used for pages such as `login.html` or any page which is intended to serve HTML content like that. It's more for images, CSS, JavaScript files. Your `login.html` file would typically be served by an [endpoint handler](https://javalin.io/documentation#endpoint-handlers) (a "route") which would be named (in your case) `/login`. – andrewJames Jan 17 '23 at 20:55
  • To try to answer your question - I am not aware of any out-of-the-box way for Javalin to serve static content by dropping the file suffix (see above comment for why I believe this does not exist). But I may be wrong. – andrewJames Jan 17 '23 at 20:56
  • Gotcha, that makes sense. So how exactly could I serve the webpage through an endpoint handler? Would I need to read the file and call ctx.html? – jchernin4 Jan 17 '23 at 21:00
  • You can use `.get("/login", ctx -> { ctx.result(in); })` where `in` is an `InputStream` of the `login.html` file (probably read from the classpath of your application, in this case). That will just serve the HTML file "as-is". Or you can use `ctx.render(...)` which allows for much more flexibility - but you have to use a renderer such as Thymeleaf for that approach. (You don't actually have to have any Thymeleaf directives in your HTML file.) – andrewJames Jan 17 '23 at 21:11
  • There's also `ctx.html(...)` - forgot about that. That takes a string (of HTML). – andrewJames Jan 17 '23 at 21:15

2 Answers2

0

I followed what andrewJames was saying and that worked for me. I was hoping there would be a cleaner way of doing this, as I'm just copy pasting the same code for every endpoint and changing the file path, but this works.

jchernin4
  • 11
  • 2
  • 7
0

Here are two examples of what was discussed in the comments to the question, for future visitors:

The first example assumes there is a simple HTML file in the application's resources/html folder.

The test.html file:

<!DOCTYPE html>
<html>
    <head>
        <title>Test</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>        
        <div>Hello world.</div>
    </body>
</html>

The /test handler:

public static void main(String[] args) {

    Javalin.create(config -> {
    })
        .get("/test", ctx -> {
            ctx.contentType(ContentType.TEXT_HTML);
            InputStream in = App.class.getResourceAsStream("/html/test.html");
            ctx.result(in);
        })
        .start(8080);
}

If you choose to configure Javalin with Thymeleaf, and if you place your HTML file in the default location expected by Thymeleaf (resources/thymeleaf), then you can do this:

.get("/test", ctx -> {
    Map<String, Object> model = new HashMap<>();
    ctx.render("test.html", model);
})

In this case, the model used by Thymeleaf for rendering is empty because you don't need to make any substitutions in your HTML file (it's not a template). But it's a short step from this to using dynamic Thymeleaf templates.

andrewJames
  • 19,570
  • 8
  • 19
  • 51