Below is my class in which i had to use both @Configuration
and @Controller
as there should be only one instance of Thymeleaf
in the entire application else i get exceptions for that. My other classes are annotated with @RequestScope
so i cannot use a singleton scoped bean. So i had a mixup of Configuration and Controller to get the result, but i feel it is a bad practice. I would appreciate any help to refactor the code and remove the bad practice.
UPDATE
I am using spring-boot 1.5.14
. I am using the following approach to process a template and keep the processed template as string.
@Controller
@Configuration
@EnableWebMvc
@ApplicationScope
public class MyThymeleafConfig {
@GetMapping("/view-template")
@ResponseBody
public void viewTemplates() {
Context context = new Context();
context.setVariable("mydata", "this is it");
String html = templateEngine().process("templates/view-to-process.html", context);
System.out.println(html);
}
/*
configuration for thymeleaf and template processing
*/
@Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(thymeleafTemplateResolver());
return templateEngine;
}
@Bean
public SpringResourceTemplateResolver thymeleafTemplateResolver() {
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setPrefix("classpath:");
templateResolver.setSuffix(".html");
templateResolver.setCacheable(false);
templateResolver.setTemplateMode(TemplateMode.HTML);
return templateResolver;
}
@Bean
public ThymeleafViewResolver thymeleafViewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
return viewResolver;
}
}
To serve static resources the following config:
@Configuration
@EnableWebMvc
public class StaticResourceConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/**")
.addResourceLocations("/static/", "classpath:static/");
}
}
UPDATE
I have also mentioned the reasons why i couldn't accept the below mentioned answers as my other classes have request scopes.
UPDATE
I have other classes with @RequestScope
like below:
@RequestScope
@Controller
public class SecondController {
@GetMapping("/viewPage")
public String viewPage(Model model) {
model.addAttribute("mydata", "sjfbsdf");
model.addAttribute("somedata", "sjdfksfjhshgdfbskdfj");
return "templates/view-to-process.html";
}
}
The @Controller annotation indicates that a particular class serves the role of a controller. There is no need to extend any controller base class or reference the Servlet API.
@Configuration annotation indicates that a class declares one or more @Bean methods and may be processed by the Spring container to generate bean definitions and service requests for those beans at runtime.
One of the most important annotations in spring is @Configuration annotation which indicates that the class has @Bean definition methods. So Spring container can process the class and generate Spring Beans to be used in the application. This annotation is part of the spring core framework.
Answer: The @Controller annotation indicates that a particular class serves the role of a controller. It does not require you to extend any controller base class or reference the Servlet API. Is This Question Helpful?
Don't put request mappings inside configuration classes, it violates the principal of separation of concerns. You can go for a approach like below.
All the application wide beans are setup in Application
class which is present in the root of the classpath. Application
class in the best place to have your thymeleaf and static resource configurations too, since the Application
class have application-scope.
@SpringBootApplication
@EnableWebMvc
public class Application{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public ViewResolver viewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
resolver.setCharacterEncoding("UTF-8");
resolver.setCache(false);
return resolver;
}
@Bean
public TemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setEnableSpringELCompiler(true);
templateEngine.addDialect(new LayoutDialect());
templateEngine.addDialect(new Java8TimeDialect());
templateEngine.setTemplateResolver(templateResolver());
return templateEngine;
}
private ITemplateResolver templateResolver() {
SpringResourceTemplateResolver resolver = new
SpringResourceTemplateResolver();
resolver.setApplicationContext(applicationContext);
resolver.setPrefix("classpath:/templates/");
resolver.setTemplateMode(TemplateMode.HTML);
return resolver;
}
}
If you put the static resources inside a folder named static or public in the classpath, springboot identify that as the location for static resources. Then you don't need to override addResourceHandlers
method. If you really want to do it, you can do it inside the Application class extending WebMvcConfigurerAdapter
. You don't need separate class to configure just static resource paths.
Don't put request mappings inside configuration classes, put them in separate controller classes like:
@Controller
public class MyController {
@GetMapping("/view-template")
@ResponseBody
public void viewTemplates() {
Context context = new Context();
context.setVariable("mydata", "this is it");
String html = templateEngine().process("templates/view-to-process.html", context);
System.out.println(html);
}
}
Of cause, springboot allows you to do it the way you like, but you'd better stick to a general approach.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With