How to configure Thymeleaf template location - java

I want to use Thymeleaf in a Spring Boot 2.1.5 based application. But I do not need it to create html output for a RestController. Instead of that I want it to create html files that the application can store on disk.
Because of this I create two beans templateResolver and templateEngine like the docs describe. The templates are stored in the same location I would use for the RestController: src/main/resources/templates. One for example is called index.html.
But no matter which path I configure (with or without classpath) I get the same error message:
templateResolver.setApplicationContext(this.applicationContext);
templateResolver.setPrefix("classpath:/resources/templates/");
templateResolver.setSuffix(".html");
java.io.FileNotFoundException: class path resource
[resources/templates/index.html] cannot be opened because it does not
exist
How do I need to configure the path to make it work a) inside STS and b) inside the created jar ?
An alternative to solving this problem would be using spring-boot-starter-thymeleaf instead and "grabbing" its generated output instead of exposing it via the embedded Tomcat but I do not know how to get this to work:
#GetMapping("/noneedforthis")
public String getIndexFileContent(#RequestParam(name="name", required=false, defaultValue="World") String name, Model model) {
model.addAttribute("name", name);
return "index";
}

I checked both the local target directory of my Eclipse workspace and the jar created by running maven install: instead of resources/templates the templates are stored in templates.
Shortening the path in my code helped and now Thymeleaf can find the templates.
Using the Spring Boot Starter for Thymeleaf would still be an interesting alternative but so far I have not found an approach.

Related

Spring Boot app deployed to Heroku doesn't locate its' thymeleaf views

My Spring Boot app runs perfectly at localhost but when I'm deploying it to Heroku, my app's controller stops seeing the views which are normally located at /templates/ directory. Why does this happen? How can I be sure that heroku actually uploads and compiles my views? If it does, should I change actual values of #RequestMapping of my #Controller class in order to make them reachable when they are at heroku?
You can find my whole working webapp here: https://github.com/slavicketernity/testik56
Here is my uploaded and runnung app: https://testik56app.herokuapp.com/login
In my case it was fault of the slashes on the beginning of the String returned by Controller's method with template location.
After I changed the String returned by controller's methods from
#RequestMapping(value = "/orders/{orderId}/create_entry")
String create(#PathVariable String orderId) {
return "/order_entries/create";
}
to
#RequestMapping(value = "/orders/{orderId}/create_entry")
String create(#PathVariable String orderId) {
return "order_entries/create";
}
then it started to work.
Are you deploying this application as a .jar? I have seen some infrastructures require that you deploy applications as a .war to provide access to your webpage directory.
If that is the issue you can apply the war plugin via gradle.
https://docs.gradle.org/current/userguide/war_plugin.html

Spring Boot resources not found

Ok, I developed a small spring boot website using thymleaf and now realized that I can't use the webapp folder if I want to package everything with the maven plugin.
To fix this I moved all my resources to src/main/resources. However, I keep getting FileNotFoundExceptions when I try to display any site (simple RequestMapping returning a String):
This is the error I get:
Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/index.html]
at org.springframework.web.context.support.ServletContextResource.getInputStream(ServletContextResource.java:157) ~[spring-web-5.0.0.BUILD-SNAPSHOT.jar:5.0.0.BUILD-SNAPSHOT]
at org.thymeleaf.spring5.templateresource.SpringResourceTemplateResource.reader(SpringResourceTemplateResource.java:103) ~[thymeleaf-spring5-3.0.3.M1.jar:3.0.3.M1]
at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:223) ~[thymeleaf-3.0.3.RELEASE.jar:3.0.3.RELEASE]
... 75 common frames omitted
And then I get the same error again when Spring tries to load my error page.
Full http://pastebin.com/raw/Csw5akHJ
Explorer
(Yes I know that only the static folder is available. Good enough for testing.)
Can anyone help me? This is getting a bit frustrating.
If you are using Thymleaf as Template Engine you should add all .html files inside resources/templates
i am not sure if this is your problem but normally i would put all the html pages inside templates directory under resources and all js and css files under static directory.
by doing so js and css files can easily accessed. for eg if i have css directory and test.css inside it. i can simply access it doing
so coming to your problem on my controller i will return pages like this.
#RequestMapping(value="/viewusers",method = RequestMethod.GET)
public String viewUsers(){
return "users/viewusers";
}
in above sample i have viewusers.html under users directory. my users directory is inside templates directory.
OK, I made some headway. While it works fine if I use the default template Engine It stops working as soon as I start using the Thymeleaf one. Apparently the default template Engine can handle classpaths automatically while I needed to switch from SpringResourceTemplateResolver to ClassLoaderTemplateResolver if I want to use thymeleaf.
So far it looks like everything is working fine. Halleluja!

Java MVC project in Spring Tool Suite additional files

I'm learning to make Java MVC project using Spring Tool Suite tool.
The path to make new project is:
File->New->SpringLegacyProject->Spring MVC Project.
My question is: which directory I have to use to add additional not-Spring files and where and what do I have to type for Spring files to see them?
For example:
css files - where to put and how to make jsp views see them, will 'link rel="" 'tag be enough?
properties files used to specify database connection or to specify messages for ReloadableResourceBundleMessageSource. In this case, do I have to create bean for this class in root-context.xml?
Thanks.
You should probably use Spring Boot (i.e. use File->New->Spring Starter Project and select Web as a starter. Place your web resources under src/main/resources/static folder. They are picked up automatically from that folder.
You should try an example project: File -> New -> Import Spring Getting Started Content and then pick "Serving Web Content" from the list.
Try some DB getting started content example to get the answer for the second part of your question.

Spring boot serving static resource

I work on spring boot application. I'm trying to serve static content with spring.
want to serve a resource stored in the /c:/frontend/files/ directory whenever a request comes in for the URL matching the pattern: /file/**:
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/file/**")
.addResourceLocations("file:///C:/frontend/files/" );
}
but when i try to access to this resource using this url: http://localhost:9999/file/app.min.js
I have this problem
There was an unexpected error (type=Not Acceptable, status=406).
Could not find acceptable representation
I resolved the problem. it's related to "spring-cloud-config-server". I just delete this config: org.springframework.cloud spring-cloud-config-server
It sounds like your project's folder structure is wrong.
Code should go under src/main/java and resources (like your javascript) should go under src/main/resources. You have a few different options where you can actually serve the files from. This post on the spring.io blog has the following to say:
Spring Boot will automatically add static web resources located within any of the following directories:
/META-INF/resources/
/resources/
/static/
/public/
Another option you also have is using webjars.
Personally, I've found it easiest to put those kind of files under src/main/resources/public. It always works without any issues for me. The interesting thing is you can put a folder named /public anywhere in your project and spring-boot will serve files out of it. You have to be really careful that it's under src/main/resources/public though if you're using a build tool like maven, as when you come to build your .jar the files won't be in the right place otherwise.

Template Development Workflow with Spring?

I'm working on a Spring WebMVC project that generates HTML output by using FreeMarker templates. A site controller returns a view name and a data model which is then fed into the view template.
Sample controller method (in /src/main/java/com/mycompany/controller.java):
#RequestMapping("/example")
public ModelAndView handleRequest() {
ModelAndView mv = new ModelAndView("my_tempate");
mv.addObject("my_data", "my_value");
return mv;
}
Sample template for this (which resides in /src/main/webapp/WEB-INF/views/my_template.ftl):
<title>Sample Template</title>
<p>I'm a sample template, I output: ${my_data}</p>
I package a .war file and deploy it to tomcat with mvn tomcat7:redeploy. This process takes about 4-5 seconds for my very small code base. For changes to the java code I'm fine with this compilation time. However for developing HTML templates it is a very unsatisfying workflow having to redeploy my .war file with every change.
Is it possible to set up Spring to not read template files from the .war file package but rather from the local file system while in development mode? So I could point in the source to an absolute path like /home/user/my_project/my_template.ftl that is parsed on every site request.

Categories