I am developing a site using Spring, Spring MVC, Thymeleaf and ran into the problem: css file with styles not being applied to my page.
The structure of the project is as follows:
java
com
tournament
config
MySpringMVCDispatcherServletInitialize.java
SpConfig.java
controllers
HomePageController.java
webapp
WEB-INF
views
css
style.css
home_page.html
style.css:
p{
font-size: 200%;
font-family: Verdana, Arial, Helvetica, sans-serif;
color: #336;
}
body{
background-color: red;
}
home_page.html:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" type="text/css" th:href="#{/css/style.css}" media="all">
</head>
<body>
<p>Hello</p>
</body>
</html>
in SpConfig there are this configs:
#Configuration
#ComponentScan("com.tournament")
#EnableWebMvc
public class SpConfig implements WebMvcConfigurer {
private final ApplicationContext applicationContext;
#Autowired
public SpringConfig(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
#Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setApplicationContext(applicationContext);
templateResolver.setPrefix("/WEB-INF/views/");
templateResolver.setSuffix(".html");
return templateResolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
templateEngine.setEnableSpringELCompiler(true);
return templateEngine;
}
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
registry.viewResolver(resolver);
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry {
registry.addResourceHandler("/css/**")
.addResourceLocations("/WEB-INF/css/");
}
In home_page.html place the cursor on th:href="#{/css/style.css}", it seems correct path to css file, but when starting the server on the page home_page.html no styles which contained in style.css. So how can I to apply this style?
Your directory structure shows that the css is in WEB-INF/views/css, but you configure /WEB-INF/css/ in addResourceLocations. According to https://www.baeldung.com/spring-mvc-static-resources, if you don't use the classpath: prefix in that string, then the path is relative to webapp/resources.
So or you need to move your CSS, or you will need to update the .addResourceLocations("/WEB-INF/css/") statement.
Related
I have a controller
#Controller
public class FirstController {
#GetMapping("/hello")
public String helloPage(#RequestParam("name") String name,
Model model){
model.addAttribute("message", name);
return "first/hello";
}
}
And view hello.html
<!doctype html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>Hello world!</h1>
<p th:text="${message}"></p>
</body>
</html>
I enter the required parameters: http://localhost:8080/hello?name=Tom
But all that the page displays is "Hello world!"
P.S. I'm working with spring core and therefore I had to write the configs by hand, here's what is in the configs:
#Configuration
#ComponentScan("com.nosferat.springapp")
#EnableWebMvc
public class SpringConfig implements WebMvcConfigurer {
#Bean
public ViewResolver viewResolver() {
var viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".html");
return viewResolver;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
Maybe it has something to do with the config
Why do you have a return "first/hello"? you should use return "hello", by the way this may be the answer to your question
i also highly suggest you to use Spring boot so your life will be easier
I'm using thymeleaf as a template engine but I cant get it to work properly.
I'm using websockets to push html to the web browser so I try to process the template with the context into a string. This string is then send to the browser to show.
My Controller class:
#Autowired
private SimpMessagingTemplate simpMessagingTemplate;
#Autowired
private SpringTemplateEngine springTemplateEngine;
private void send() {
Map<String, Object> params = new HashMap<>();
params.put("name", "Willem");
final IContext cts = new Context(Locale.ITALY, params);
String result = springTemplateEngine.process("hello", ctx);
simpMessagingTemplate.convertAndSend(destination, result);
}
My thymeleaf configuration:
#Configuration
public class ThymeleafConfig extends WebMvcConfigurerAdapter {
#Bean
public ClassLoaderTemplateResolver templateResolver() {
ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
templateResolver.setPrefix("thymeleaf/");
templateResolver.setCacheable(false);
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
templateResolver.setCharacterEncoding("UTF-8");
return templateResolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
return templateEngine;
}
#Bean
public ViewResolver viewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine( templateEngine());
viewResolver.setCharacterEncoding("UTF-8");
return viewResolver;
}
}
And my hello.html template:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns="http://www.w3.org/1999/xhtml">
<body>
<h2>Hello ${name} - THYMELEAF</h2>
</body>
</html>
When I print the string result from the send method, I get this output:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<h2>Hello ${name} - THYMELEAF</h2>
</body>
</html>
Whatever I try, I can't get the parameters to be passed to the template.
You try java code:
private void send() {
Context context = new Context();
context.setVariable("name", "hello");
String result = springTemplateEngine.process("hello", context);
simpMessagingTemplate.convertAndSend(destination, result);
}
Html: hello.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<h2>Hello <b th:text="${name}"></b> - THYMELEAF</h2>
</body>
</html>
When attempting to localize a static string the message is displayed surrounded with questionmarks "??"
e.g. ??ticket.type_en_US??
<p th:text="#{ticket.type}">Blah</p>
I am using SpringBoot 1.3.6.RELEASE
Thymeleaf: 3.0.0.RELEASE
thymeleaf-spring4 artifact
I have configured the basename of my messages in application.properties
and the contents of that messages.properties and messages_en_US.properties is:
ticket.type=BUGS!!!!
Config:
spring.messages.basename=messages
Output on startup:
2016-07-19 08:38:28.673 DEBUG 5175 --- [ main]
ationConfigEmbeddedWebApplicationContext : Using MessageSource
[org.springframework.context.support.ResourceBundleMessageSource:
basenames=[messages]]
I also tried programatically using the MessageResource in the code below. I placed the messages.properties file in the same folder as the application.properties file. src/main/resources/
#Configuration
#ComponentScan("controller")
public class WebConfig extends WebMvcConfigurerAdapter implements ApplicationContextAware{
private ApplicationContext applicationContext;
#Autowired
private MessageSource messageSource;
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
#Bean
public ViewResolver viewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
resolver.setCharacterEncoding("UTF-8");
return resolver;
}
#Bean
public TemplateEngine templateEngine() {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setTemplateResolver(templateResolver());
engine.setMessageSource(messageSource);
return engine;
}
#Bean
public ITemplateResolver templateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setApplicationContext(applicationContext);
resolver.setPrefix("/WEB-INF/templates/");
resolver.setTemplateMode(TemplateMode.HTML);
return resolver;
}
}
For completeness here is my application config (like others I had to exluse the Thymeleaf class):
#SpringBootApplication(exclude={org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration.class})
public class Application {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
}
}
I have also verified that the message bundles are being loaded by pring out the contents on one of my REST end-point calls:
#Autowired
private MessageSource messageSource;
#GET
#Produces("application/json")
public List<MyData> getData() {
System.out.println("HERE 1 in Conversions");
System.out.println(messageSource.getMessage("ticket.type", null, Locale.US));
return getTheData();
}
This prints out the following so I know spring-boot is loading the resource bundles, but Thymeleaf is not picking them up somehow:
BUGS!!!!
Here is my full HTML page, perhaps there is an issue with it:
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Kitchen Sink</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<link href="http://cdn.jsdelivr.net/webjars/bootstrap/3.3.4/css/bootstrap.min.css"
th:href="#{/webjars/bootstrap/3.3.4/css/bootstrap.min.css}"
rel="stylesheet" media="screen" />
<script src="http://cdn.jsdelivr.net/webjars/jquery/2.1.4/jquery.min.js"
th:src="#{/webjars/jquery/2.1.4/jquery.min.js}"></script>
<link href="../static/css/mike.css"
th:href="#{css/mike.css}" rel="stylesheet" media="screen"/>
</head>
<body>
<div class="container">
<div class="jumbotron">
<h1>Hello</h1>
<h2>Welcome to the Kitchen Sink!</h2>
<p th:text="#{ticket.type}">Blah</p>
<p th:text="#{test.type}">dssfgf</p>
</div>
</body>
</html>
ok, so I figured it out. Thanks #M.Deinum for poitning out that I should just let spring-boot and Thymeleaf do what they are supposed to do.
I had to set the:
engine.setMessageSource(messageSource);
and also add the:
#Bean
to the 2 other functions. This allowed the MessageSource to be passed into the engine and resolve the properties correctly.
I will update the question above with the correct source so people can use it for referene
Please add
#EnableAutoConfiguration
in your Spring boot startup its look like
#EnableAutoConfiguration
#SpringBootApplication
public class Application {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
}
}
I had a similar problem, and code from your post didn't work for me. The source of my issue was, that I didn't have message.proprerties (without any language).
I had:
messages_en.properties
messages_de.properties
messages_es.properties
but it didn't work.
It started working only when I added
messages.properties
I'm making a web app using Spring 4, the Spring security module and tomcat 8. I'm trying to include some css files and js files in a .jsp file, but it's not working. When I check in the sources tag in Chrome the content of the css seems to be a log in form. I suspect that it may have something to do with spring security.
My css file is included like this in the .jsp
<link href="<c:url value='resources/css/materialize.min.css' />" rel="stylesheet"
type="text/css"></link>
This is the WebConfig file
#Configuration
#ComponentScan(basePackages = "mypackage")
#EnableWebMvc
#EnableTransactionManagement
public class WebAppConfig extends WebMvcConfigurerAdapter {
#Bean
public InternalResourceViewResolver viewResolver(){
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}
#Autowired
#Bean
public HibernateTransactionManager transactionManager(SessionFactory sessionFactory){
HibernateTransactionManager transactionManager = new HibernateTransactionManager(sessionFactory);
return transactionManager;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
This is the SecurityConfig file
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/js/**", "/resources/css/**", "/resources/img/**", "/resources/font/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin().loginPage("/signin")
.failureUrl("/signin?param.error=bad_credentials")
.and().logout().logoutUrl("/signout")
.and().authorizeRequests()
.antMatchers("/favicon.ico", "/resources/css/**", "/resources/font/**",
"/resources/js/**", "/auth/**", "/signin/**", "/signup/**", "/disconnect/facebook").permitAll()
.antMatchers("/**").authenticated()
.and()
.rememberMe().
and().csrf();
}
}
According to other answers here in stackoverflow it should work with the code that I have but the css only returns this:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:social="http://spring.io/springsocial"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="layout">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<div id="content" >
<form id="signin" action="signup" method="post">
<input type="hidden" name="" value=""/>
<div class="formInfo">
</div>
<fieldset>
<label for="login">Email</label>
<input id="login" name="email" type="text" size="25"></input>
<label for="Nombre">Email</label>
<input id="nombre" name="nombre" type="text" size="25"></input>
<label for="password">Password</label>
<input id="password" name="contrasena" type="password" size="25"></input>
</fieldset>
<button type="submit">Sign In</button>
<p>Or you can signin with a new account.</p>
</form>
</div>
All my css and js files are inside WebContent/resources
I solved the problem, apparently there was an ambiguous routing in one of my controllers, so when I tried to access a url that started with "/resources" it routed it to the controller, and thus returned a .jsp instead of the css/js/image. My original controller binded the url in the #Controller, and left the #RequestMapping without indicating the route.
#Controller("/signup")
public class SignUpController {
#RequestMapping(method=RequestMethod.GET)
public String signUpForm(){
...
}
#RequestMapping(method=RequestMethod.POST)
public String crearUsuario(HttpServletRequest request){
...
}
So I changed the #Controller annotation, and put the url in each #RequestMapping like this:
#Controller
public class SignUpController {
#RequestMapping(value="/signup", method=RequestMethod.GET)
public String signUpForm(){}
#RequestMapping(value="/signup",method=RequestMethod.POST)
public String crearUsuario(HttpServletRequest request){}
}
I have a string variable that I create in a controller class and I want to print it in a jsp page using this
${time}
My code works if I don't use a thymeleaf view resolver, but if I do use one it doesn't work.
Here is my controller class
#Controller
public class HomeController {
#RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
String thetime = "the time";
model.addAttribute("time", thetime );
return "home.jsp";
}
And my .jsp page
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>
Hello world!
</h1>
<P> The time on the server is ${time}. </P>
</body>
</html>
My thymeleaf resolver configuration:
#Bean
public ServletContextTemplateResolver templateResolver() {
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".html");
resolver.setTemplateMode("HTML5");
resolver.setOrder(1);
resolver.setCacheable(false);
return resolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setTemplateResolver(templateResolver());
engine.setMessageSource(messageSource());
return engine;
}
#Bean
public ThymeleafViewResolver thymeleafViewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
String[] vistas = {"*.html", "*.jsp"};
resolver.setTemplateEngine(templateEngine());
resolver.setOrder(1);
resolver.setViewNames(vistas);
resolver.setCache(false);
return resolver;
}
#Bean
public SpringResourceTemplateResolver thymeleafSpringResource() {
SpringResourceTemplateResolver vista = new SpringResourceTemplateResolver();
vista.setTemplateMode("HTML5");
return vista;
}
Is there a special notation to do this with thymeleaf?
You have set your view resolver to be Thymeleaf but you trying to render JSP thats why it isn't working.
if you want that file converted to Thymeleaf format it needs to look like this (or approx) and the extension has to be .html not .jsp:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Home</title>
</head>
<body>
<h1>
Hello world!
</h1>
<P> The time on the server is <div th:text=#{time}>TIME_PLACEHOLDER</div> </P>
</body>
</html>
Aesir's answer worked, but it wasn't necesary to change my .jsp page to a .html page. I just put this
<div th:text="${time}">TIME_PLACEHOLDER</div>
instead of just ${time}, and it worked without the HTML header that was suggested.