thymeleaf 3 spring 5 load css - css

I'm trying to configure Spring5 and Thymeleaf3 togheter.
I'm working on Eclipse, I build with clean install and run the app with springboot:run.
I've setup a controller and a couple of template and css but it seems that thymeleaf cannot find the css, in the browser it shows the template (es. 'panda.html') without loading the css but if I open manually the .html the browser load also the .css . What i need to add to my code?
this is the mapping
#Controller
public class MyController {
#Autowired
UtentiRepository utentiRepository;
#GetMapping("/gab")
public String panda(Model model) {
return "panda";
}
and this is the template resolver
#Bean
public SpringResourceTemplateResolver templatecssResolver() {
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setApplicationContext(applicationContext);
templateResolver.setPrefix("classpath:/static/css/");
templateResolver.setSuffix(".css");
return templateResolver;
}
#Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setApplicationContext(applicationContext);
templateResolver.setPrefix("classpath:/templates/");
templateResolver.setSuffix(".html");
return templateResolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.addTemplateResolver(templatecssResolver());
templateEngine.setTemplateResolver(templateResolver());
templateEngine.setEnableSpringELCompiler(true);
return templateEngine;
}
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
registry.viewResolver(resolver);
}

You've to override the addResourceHandlers(..) method of the you calls that implements the WebMvcConfigurerAdapter not as a bean (SpringResourceTemplateResolver )
SO just add the overiding method
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/css/**")
.addResourceLocations("classpath:/static/css/");
}
in your template use
<link href="<c:url value="/css/style.css" />" rel="stylesheet">
or using themleaf
<link th:href="#{/css/style.css}" />" rel="stylesheet">

Related

Thymeleaf View Resolver with SpringMVC webapp

How if one can use ThymeleafViewResolver as a defalt view resolver.
Currentely my WebMvcConfig looks like this
#Configuration
#ComponentScan(basePackages="com.greatLearning.ticketAPI.controller")
public class WebMvcConfig implements WebMvcConfigurer {
#Autowired
ApplicationContext applicationContext;
// #Override
// public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
// configurer.enable();
// }
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
//Thymeleaf ViewResolver
#Bean
public SpringResourceTemplateResolver templateResolver(){
// SpringResourceTemplateResolver automatically integrates with Spring's own
// resource resolution infrastructure, which is highly recommended.
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setApplicationContext(this.applicationContext);
templateResolver.setPrefix("/WEB-INF/views/");
templateResolver.setSuffix(".html");
// HTML is the default value, added here for the sake of clarity.
templateResolver.setTemplateMode(TemplateMode.HTML);
// Template cache is true by default. Set to false if you want
// templates to be automatically updated when modified.
templateResolver.setCacheable(true);
return templateResolver;
}
#Bean
public SpringTemplateEngine templateEngine(){
// SpringTemplateEngine automatically applies SpringStandardDialect and
// enables Spring's own MessageSource message resolution mechanisms.
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
// Enabling the SpringEL compiler with Spring 4.2.4 or newer can
// speed up execution in most scenarios, but might be incompatible
// with specific cases when expressions in one template are reused
// across different data types, so this flag is "false" by default
// for safer backwards compatibility.
templateEngine.setEnableSpringELCompiler(true);
return templateEngine;
}
#Bean
public ThymeleafViewResolver viewResolver(){
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
// NOTE 'order' and 'viewNames' are optional
viewResolver.setOrder(1);
viewResolver.setViewNames(new String[] {".html", ".xhtml"});
return viewResolver;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/resources/**")
.addResourceLocations("/resources/");
}
}
for *.jsp view it is working just fine, but I want to use Thymeleaf to resolve my .html templates becasue I don't want to use *.jsp .
One thing to note is that in my controller
TestController.java
#RequestMapping("/hello")
public String method1() {
return "hello";
}
#RequestMapping("/hello2")
#ResponseBody
public String method2() {
return "hello"; //This works fine
}
when I hit /hello api this is what I get
How do I configre viewResolver so that spring picks up ThymeleafViewResolver to resolve html rather than jsp
Problem Solved!!!!!
Here is what I did after an hour of debugging the libraries
in WebMvcConfig.java I revomed the public InternalResourceViewResolver resolver() method as it is sed to configure jsp.
Now in ThymeleafViewResolver viewResolver() remove these two:
viewResolver.setOrder(1);
viewResolver.setViewNames(new String[] {".html", ".xhtml"});
got help through debgging and [this post](Problem Solved!!!!!
Here is what I did after an hour of debugging the libraries
in WebMvcConfig.java I revomed the public InternalResourceViewResolver resolver() method as it is sed to configure jsp.
Now in ThymeleafViewResolver viewResolver() remove these two:
viewResolver.setOrder(1);
viewResolver.setViewNames(new String[] {".html", ".xhtml"});
got help through debgging and this post.
As to why I will answer if anyone is interested. :)

Camel Rest and RestController in the same project

I have a camel rest in my project and a servlet is configured for it. At the moment I'm trying to add a regular RestController without camel. Can two types of rest be in the same project?
For example
#Override
public void configure() throws Exception {
rest("/dictionary/get-dictionary")
.get()
.param().name("dictionary").required(true).type(RestParamType.query).endParam()
.param().name("name").required(true).type(RestParamType.query).endParam()
.....
.endRest();
CamelServlet implemented for camel
#RestController
#RequestMapping("/createOrder")
#RequiredArgsConstructor
public class OrderController {
private final OrderService OrderService;
#PostMapping
public void createForm(#RequestBody App app) {
orderService.createFullOrder(app);
}
}
When I request createOrder, I always get 404. How can I make both types of controllers work?
Thank in advice
Solution
#Configuration
public class AppConfig {
#Bean
public DispatcherServlet dispatcherServlet() {
return new DispatcherServlet();
}
#SuppressWarnings("rawtypes")
#Bean
public ServletRegistrationBean axisServletRegistrationBean() {
#SuppressWarnings("unchecked")
ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet(), "/createOrder");
registration.addUrlMappings("/createOrder");
return registration;
}
}
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.package.package")
public class WebConfig {
}

Spring redis unable to autowire repository

I'm using custom crudrespository to persist data in redis. However, I'm unable to autowire custom repository.
All the configuration seems correct and redis is running on my local.
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface CustomRepository extends CrudRepository<String,
Long> {
String get(String key);
void put(String key, String value);
}
//////////
public class StorageServiceImpl implements IStorageService {
#Autowired
private CustomRepository respository;
#Override
public void saveParameter() {
this.respository.put("key1","value1");
}
#Override
public String getParameter() {
return this.respository.get("key1");
}
/////
#Service
public interface IStorageService {
void saveParameter();
String getParameter();
}
///////
#SpringBootApplication(scanBasePackages = {"com.example.cache"})
#EnableRedisRepositories(basePackages = {"com.example.cache.repository"})
public class ApplicationConfiguration {
public static void main(String[] args){
SpringApplication.run(ApplicationConfiguration.class, args);
new StorageServiceImpl().saveParameter();
System.out.println(new StorageServiceImpl().getParameter());
}
}
When I try running this application using gradle bootRun, I get
Exception in thread "main" java.lang.NullPointerException
at com.example.cache.impl.StorageServiceImpl.saveParameter(StorageServiceImpl.java:16)
at com.example.cache.ApplicationConfiguration.main(ApplicationConfiguration.java:17)
Not sure what's wrong?
You can't use new on any bean, you need to #Autowire it. The annotations only work with spring managed beans at every level.
Add a new bean with a a storage service and a method that makes your call after it is created.
Also, I can't remember if the spring-boot creates the bean if there is only one implementation but I believe your StorageServiceImpl needs the #Service annotation, not the interface.
Delete this from your ApplicationConfiguration class.
new StorageServiceImpl().saveParameter();
System.out.println(new StorageServiceImpl().getParameter());
Then add this new class.
#Service
public class Startup {
#Autowired
IStorageService storageService;
#PostConstruct
public void init(){
storageService.saveParameter();
System.out.println(storageService().getParameter());
}
}
And you need a config
#Configuration
#EnableRedisRepositories
public class ApplicationConfig {
#Bean
public RedisConnectionFactory connectionFactory() {
return new JedisConnectionFactory();
}
#Bean
public RedisTemplate<?, ?> redisTemplate() {
RedisTemplate<byte[], byte[]> template = new RedisTemplate<byte[], byte[]>();
return template;
}
}

Spring Boot custom static resource location outside of project

How can I add a custom resource location that is on for example my D drive in folder called Resources.
#Configuration
public class StaticResourceConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
registry.addResourceHandler("/**").addResourceLocations("D:/Resources/");
}
}
This doesn't work.
This is my application class and the only other configuration file.
#SpringBootApplication
public class Application {
public static void main(String args[]){
SpringApplication.run(Application.class, args);
}
#Bean // for websocket endpoints
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
#Bean
public PasswordEncoder bcryptPasswordEncoder(){
return new BCryptPasswordEncoder();
}
}
You should state your location using the file prefix, check more here . So it should be
registry.addResourceHandler("/**").addResourceLocations("file:///D:/Resources/");
Try /D:/Resources/. Absolute path must start with /

Swagger: Not showing UI

I want to use Swagger with Spring MVC. I have following entries in the build.gradle file
compile 'com.mangofactory:swagger-springmvc:0.9.4'
compile 'com.wordnik:swagger-annotations:1.3.12'
compile 'org.webjars:swagger-ui:2.0.12'
I have enable it using #EnableSwagger annotation.
#EnableAutoConfiguration(exclude = {EmbeddedServletContainerAutoConfiguration.EmbeddedJetty.class, LiquibaseAutoConfiguration.class, org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration.class})
#EnableSwagger
#EnableWebMvc
#Configuration
public class App extends WebMvcConfigurerAdapter{
#Bean
ProtobufHttpMessageConverter protobufHttpMessageConverter() {
return new ProtobufHttpMessageConverter();
}
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
private SpringSwaggerConfig springSwaggerConfig;
#SuppressWarnings("SpringJavaAutowiringInspection")
#Autowired
public void setSpringSwaggerConfig(SpringSwaggerConfig springSwaggerConfig) {
this.springSwaggerConfig = springSwaggerConfig;
}
#Bean
public SwaggerSpringMvcPlugin customImplementation(){
return new SwaggerSpringMvcPlugin(this.springSwaggerConfig)
.apiInfo(apiInfo())
.includePatterns(".*feed.*"); // assuming the API lives at something like http://myapp/api
}
private ApiInfo apiInfo() {
ApiInfo apiInfo = new ApiInfo(
"My Project's REST API",
"This is a description of your API.",
"API TOS",
"me#wherever.com",
"API License",
"API License URL"
);
return apiInfo;
}
#Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler("*.html").addResourceLocations("/");
}
}
But when run the application using spring boot and hit the endpoint http://localhost:8080/api-docs, I just see the response in Json,
{"apiVersion":"1.0","apis":[{"description":"Basic Error Controller","path":"/default/basic-error-controller","position":0},{"description":"Manage people","path":"/default/people","position":0}],"authorizations":{},"info":{"contact":"Contact Email","description":"Api Description","license":"Licence Type","licenseUrl":"License URL","termsOfServiceUrl":"Api terms of service","title":"default Title"},"swaggerVersion":"1.2"}
I copied the static files from swagger-ui and copied it to my /main/webapp/doc
I am still missing fancy UI.

Resources