Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

error template resolution Spring Boot #304

Open
maxwellt opened this issue Dec 4, 2023 · 4 comments
Open

error template resolution Spring Boot #304

maxwellt opened this issue Dec 4, 2023 · 4 comments

Comments

@maxwellt
Copy link

maxwellt commented Dec 4, 2023

According to the documentation of Spring Boot it is possible to define templates that should be used when a specific HTTP status code occurs.

I have noticed when I place a 404.jte in src/main/resources/templates/error it doesn't work. I have tried the same thing with Thymeleaf and that does work.

Digging through the Spring code I saw that in order to resolve the error view, it goes to the DefaultErrorViewResolver#resolveError, where there is a list of templateAvailabilityProviders. These providers are Thymeleaf, Freemarker, Jsp, ... the supported templating engines of Spring (Boot).

I looked for an easy way to register a custom JteTemplateAvailabilityProvider but found no such luck, the only reference in the Spring Code to for instance ThymeleafTemplateAvailabilityProvider is in the Spring autoconfiguration library, namely in the META-INF/spring.factories file:

# Template Availability Providers
org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.mustache.MustacheTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.web.servlet.JspTemplateAvailabilityProvider

I'm not that experienced with the autoconfiguration bits of Spring Boot, but I tried to add my own META-INF/spring.factories file in my own project:

org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\
  care.animax.pms.web.config.WebConfig.JteTemplateAvailabilityProvider

And the JteTemplateAvailabilityProvider class looks like this:

    class JteTemplateAvailabilityProvider implements TemplateAvailabilityProvider {

        @Override
        public boolean isTemplateAvailable(String view, Environment environment, ClassLoader classLoader, ResourceLoader resourceLoader) {
            return resourceLoader.getResource("classpath:/templates/" + view + ".jte").exists();
        }
    }

This actually worked, when I place a debug point in DefaultErrorViewResolver#resolveError, I now see my own provider listed there as well and the JTE template is resolved properly.

Although this works, I'm not sure it's logical that I add this to my own project, should this not be part of the jte-spring-boot-starter project?

I have tried making it more generic, using the gg.jte.templateLocation and gg.jte.templateSuffix properties, while it works for the suffix, the templateLocation doesn't work.

@maxwellt
Copy link
Author

@casid just wondering if you had time to have a look at this to give me feedback?

@tschuehly perhaps you could have a look as well as I know you have a lot of experience using JTE and Spring Boot together and I think Casid doesn't use Spring Boot that much?

@tschuehly
Copy link
Contributor

Hey @maxwellt,

Without looking further into it I would say we need to register a bean of type TemplateAvailabilityProvider in the JteAutoConfiguration of the spring boot starter.
The spring.factories is for registering Configuration Classes that are being used when using a library as dependency.
This is already done for the JteAutoConfiguration.

@casid
Copy link
Owner

casid commented Feb 17, 2024

@maxwellt sorry for the late reply! I don't use Spring Boot, so I'm unfortunately not able to give any meaningful recommendations here.

@hakantkn
Copy link

As a workaround register a custom ErrorViewResolver.
With this method you can use templates in jte/error/.

@Bean
public ErrorViewResolver customErrorViewResolver() {
    return (request, status, model) -> {
        if (status.is4xxClientError()) {
            return new ModelAndView("error/4xx");
        }

        if (status.is5xxServerError()) {
            return new ModelAndView("error/5xx");
        }

        return null;
    };
}

https://docs.spring.io/spring-boot/reference/web/servlet.html#web.servlet.spring-mvc.error-handling

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants