How to locate Thymeleaf template from spring boot - java

I am trying to follow this tutorial at http://www.thymeleaf.org/doc/articles/springmvcaccessdata.html to learn how to send responses to Thymeleaf template. But I get this error: Cannot find template location: classpath:/templates/ (please add some templates or check your Thymeleaf configuration)
I put the message.html file in Other Sources directory and inside src/main/resources under <default package>.
So the structure looks like :
SomeProject
-Other Sources
--src/main/resources
---<default package>
----message.html
I was wondering why it shows under <default package> but not under <template> ? Could it be the problem? If so how am I supposed to change it? I am using netbeans and maven. Any ideas please? These are the dependencies I have in my pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
In the controller I have
#RequestMapping(value = "message", method = RequestMethod.GET)
public String messages(Model model) {
model.addAttribute("messages", messageRepository.findAll());
return "message";
}
And in the view:
<ul th:each="message : ${messages}">
<li th:text="${message.id}">1</li>
<li>Title ...</li>
<li th:text="${message.text}">Text ...</li>
</ul>

Spring Boot includes auto-configuration support for the thymeleaf templating engines, your templates will be picked up automatically from src/main/resources/templates.
if you are customize you template location then use below thymeleaf property configuration available in Spring Boot.
spring.thymeleaf.check-template=true # Check that the template exists before rendering it.
spring.thymeleaf.check-template-location=true # Check that the templates location exists.
spring.thymeleaf.enabled=true # Enable MVC Thymeleaf view resolution.
spring.thymeleaf.prefix=classpath:/templates/ # Prefix that gets prepended to view names when building a URL.
spring.thymeleaf.suffix=.html # Suffix that gets appended to view names when building a URL.

The default directory location for thymeleaf templates is:
src/main/resources/templates
The other paths are standard conventions for Spring Boot.

2 things here :
1. If you are using Maven, and I assume no customizations to folder names. Then the folder name should be src instead of source.
2. Once the folder has been renamed move your templates into 'templates' folder inside src/resources this should run fine.

For Thymeleaf template files put in folder src/main/resources/templates/ and it will work for you also do check out http://www.mkyong.com/spring-boot/spring-boot-hello-world-example-thymeleaf/ . Hope you will find it easy to kick start thymeleaf with spring boot.

I had the same problem with Spring boot + Gradle and these are the steps that I followed to resolve it:
Print out the classpath
Once I established that the resources folder was not being included in the classpath, I reloaded the application from disk:
Gradle clean the project

I see a lot of issues regarding the ThymeLeaf /templates not found problem.
For everyone using Eclipse or STS the solution is maybe simpler then any type of configuration.
In the course of the project operation with maven, that is compile, clean, build and others, the final deployment Output Directory on your eclipse workspace (or staging area)
[eclipseprojectrootfolder]/target/
can erase some of the output directory structure and not re-created them it properly.
In my case I went for all sorts of solutions on application.properties, changing the autoconfig on the Spring app to no avail.
The solution was simple:
Just look inside
[eclipseprojectrootfolder]/target/classes
and see if in that directory you can find the directories
[eclipseprojectrootfolder]/target/classes/templates/
and
[eclipseprojectrootfolder]/target/classes/static/
Those are the folders inside the resources directory:
[eclipseprojectrootfolder]/src/main/resources
simply Copy the folders inside [eclipseprojectrootfolder]/src/main/resources, that is the
/templates
/static
into [eclipseprojectrootfolder]/target/classes
That is the Solution.
Spring is complaining exactly because of that ..can not find /templates ... because the directory on the Output deployment folder/directory may indeed not be there ...
Just recreate the directory manually and all will be fine.
Important note, Of course when I mention that a manual copy of the directories may be necessary this means we need to recreate the directories And the files inside that are the templates and static content for thymeleaf.

Related

Spring boot custom starter org.springframework.boot.autoconfigure.AutoConfiguration.import not detecting configuration classes version 2.7.2

I've read that I should not open an issue on github so I ask here. I've digged into the code and for example spring-boot-actuator-autoconfigure doesn't define the #Configuration\#AutoConfiguration classes inside META-INF/spring.factories follow the content of the file:
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.boot.actuate.autoconfigure.metrics.ValidationFailureAnalyzer
I've checked and ValidationFailureAnalyzer is not even annotated with #Configuration\#AutoConfiguration. Then I see the file META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports declaring all the classes #AutoConfiguration follow a little extraction of the file:
org.springframework.boot.actuate.autoconfigure.amqp.RabbitHealthContributorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.audit.AuditAutoConfiguration
org.springframework.boot.actuate.autoconfigure.audit.AuditEventsEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.availability.AvailabilityHealthContributorAutoConfiguration
...
all these classes are annotated with #AutoConfiguration. So far so good If we read the docs they say that:
Spring Boot checks for the presence of a META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports file within your published jar.
Indeed if we import:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.7.3</version>
</dependency>
everything works just fine. I'm not skilled with gradle but I don't see any special dependecy in spring-boot-actuator-starter or spring-boot-actuator-autoconfigure.
Searching on google I've found a discussion here where they say:
In Spring Boot v. 2.7 auto-configuration registration is moved from spring.factories to a new file named META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports.
Each line contains the fully qualified name of the auto-configuration.
For backwards compatibility, entries in spring.factories will still be honored.
But honestly I've tryed to move the configuration classes in the new file but the configuration class is not loaded. I've writed an example here.
My org.springframework.boot.autoconfigure.AutoConfiguration.imports file:
com.example.springbootstarterexample.configuration.Config
If I move to the old configuration spring.factries everything works fine.
My #AutoConfiguration class:
#AutoConfiguration(after = JpaRepositoriesAutoConfiguration.class)
//#AutoConfigureAfter(JpaRepositoriesAutoConfiguration.class)
#EnableJpaRepositories(basePackages = "com.example.springbootstarterexample.repository")
#Import({SomeServiceImpl.class, SomeEntityController.class})
public class ExampleAutoConfiguration {
}
am I doing something wrong? why the spring-boot-starter-actuator works and my spring-boot-starter-example dosn't?
Your file is called org.springframework.boot.autoconfigure.AutoConfiguration.import,
and must be org.springframework.boot.autoconfigure.AutoConfiguration.imports (notice the extra s) at the end.

Logging system failed to initialize using configuration from 'classpath:logger/logback-spring.xml'

I use Spring boot 2.3.0.RELEASE.
application.properties
spring.profiles.active=dev
logging.config=classpath:logger/logback-spring.xml
logging.file.dir=reception-electronic-docs
logging.file.name.var=reception-electronic-docs.log
logging.file.archive.format.name=reception-electronic-docs.%d{dd-MM-yyyy}.log
Previously this code worked (Srping boot 2.2.5.RELEASE).
I use multi module structure in the project. But there, the Central pom does not manage the entire project. I create microservices.
During start up an application encounter an error:
Logging system failed to initialize using configuration from 'classpath:logger/logback-spring.xml'
java.io.FileNotFoundException: class path resource [logger/logback-spring.xml] cannot be resolved to URL because it does not exist
at org.springframework.util.ResourceUtils.getURL(ResourceUtils.java:137)
What are any ideas to correct this?
I add an dependencies
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
<version>3.1.2</version>
</dependency>
But I don't understand reason.
After I removed the dependency. But my app runs without errors. I'm at a loss.

FOP 2.3: Problems wiht fo:external-graphic

This is my case when i execute my java jar application in server, not directly from IDE.
I have config files in this path: C:\Temp\myuser\myappname\config\xslt. The main archives are header.jpg, fopfile.xconf and style.stl
This applications calls to Zxing library to generate a qr code in order to attach to a PDF new file. My application runs in C:\Temp\myapp\myapp.jar, so the gneerated QRCode file in png format, will be saved in that path with name qrcode.png.
My xsl-fo file uses the infamous tag fo:external-graphic. For both cases I use:
<fo:external-graphic src="url('file:\\C:\Temp\myuser\myappname\config\xslt\header.jpg')"/>
<fo:external-graphic src="url('file:\\C:\Temp\myapp\qrcode.png')"/>
But again the jar crushes and says
GRAVE: image not found, every time. I tried changing paths and the same error happens.
Now look, If i run this app from IDE -VSCode- this problem never happens.
Please guys help us what can we do? I read all the docs in the tutorial from apache but again nothing works.
note: I generate the jar via this: mvn clean compile assembly:single -f, so i create opne jar with all dependencies embedded in.
<!--Just put this first dependency **xmlgraphics-commons** before the **fop** dependency-->
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>xmlgraphics-commons</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>fop</artifactId>
<version>2.3</version>
</dependency>

Specify swagger.json url for swagger UI wildfly swarm

I have REST application with Wildfly Swarm and using default settings I have swagger.json on url /swagger or /swagger.json and ui for swagger on url /swagger-ui. But UI parsing petstore from example by default. How is it possible to configure default path for UI to my json file? I have next dependencies for swagger:
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>swagger</artifactId>
</dependency>
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>swagger-webapp</artifactId>
</dependency>
You could give the swagger-ui an url parameter that links to your swagger.json. For instance:
http://localhost:8080/swagger-ui/index.html?url=/swagger.json
You can create your own Swagger-ui webapplication. Just take the static files (html, js, css, img) from an example project. Now you can edit the index.html and define your own specific swagger.json location.
There is a servlet in swagger-webapp that does what you are looking for. It's just not documented at all. https://github.com/thorntail/thorntail/blob/master/fractions/swagger-webapp/src/main/java/org/wildfly/swarm/swagger/webapp/runtime/SwaggerDefaultUrlChangerServlet.java
I added this system-property to my project-defaults.yml and now swagger-ui launches pointing to my swagger.json
swarm:
swagger:
web-app:
json:
path: /rest/swagger.json

Refreshing static content with Spring MVC and Boot

I'm evaluating Spring MVC & Boot and AngularJs for building web applications. I've run into the problem that when I make modifications to my static content (html, js, css), I have to restart the application every time. I hope there is a some way of solving that because restarting the whole application for static content changes is not efficient. Every other web app framework I've tried allows updating static content files on the fly(even just Spring MVC and plain old WAR application).
I've setup my project from "Building a RESTful Web Service with Spring Boot Actuator" guide (http://spring.io/guides/gs/actuator-service/). Basically it uses Spring Boot and MVC controllers to create a REST service. In addition, I've used "Consuming a RESTful Web Service with AngularJS" guide (http://spring.io/guides/gs/consuming-rest-angularjs/) to build a frontend with AngularJS. It creates a web page that displays the response from the REST service. The only change I've made is that the requests are made to my application instead of "http://rest-service.guides.spring.io/greeting". My static content is stored in "src/main/resources/public" folder. This setup works correctly except it doesn't reload static content.
A recap of the original problem
I've run into the problem that when I make modifications to my static content (html, js, css), I have to restart the application every time
I had the same problem and finally solved it by adding
<configuration>
<addResources>true</addResources>
</configuration>
to spring-boot-maven-plugin in the pom.xml
I got confused by this spring-boot-devtools thing, but it had no effect whatever I did.
My static content is stored in "src/main/resources/public" folder.
Your path is just fine. src/main/resources/static is also fine.
Ah ... I came across this issue too.
Instead of putting your static content in the classpath src/main/resources/public folder, put them in src/main/webapp, the same as you would any other Java web app. The embedded Tomcat will automatically reload them whenever they change.
As mentioned in the comments, the default configuration will not include the resources that are in src\main\webapp. To get around this issue, you can just add the following to your pom.xml <build> node:
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/classes/static</outputDirectory>
<resources>
<resource>
<directory>src/main/webapp</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
By using the resources plugin, you are able to do your local development by running the executable JAR:
java -jar target/.jar
While that is running you can use Chrome Dev Tools or whatever IDE you like for modifying the files, without restarts. However, whenever you run your build, then the package generated will include all of the files under src\main\webapp in src\main\resources\static.
The docs say "all modern IDEs allow reloading of static resources and usually also hot-swapping of Java class changes" (https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/html/howto.html#howto-hotswapping). It's true. Eclipse does it more or less by default, and I'm not an IntelliJ user, but from what I understand you can configure it to build automatically as well.
A colleague and I came across this issue as well. We found the answer in the IntelliJ documentation...
On the main menu, choose Run | Reload Changed Classes
My solution (written in Kotlin but is quite obvious):
#Controller
class WebController : WebMvcConfigurerAdapter() {
override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
System.getProperty("resources.local.path")?.let {
registry.addResourceHandler("/**").addResourceLocations(it)
}
}
...
}
Main idea is you can add your own resource handler conditionally. E.g. if some system property is set (resources.local.path) then add resource location with value from the property. Then you set this property in development with some reasonable value like '-Dresources.local.path=file:/Users/andrey/Projects/gsp-test/src/main/resources/static/'.
Do not forget trailing slash.
I am using 1.5.8.RELEASE.
It instantly updates my changes especially static files or jsp files.
If you are using Maven. You need to add this in pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
And you have to start Spring Boot with this:
mvn clean spring-boot:run
Full example and more detail here https://www.surasint.com/spring-boot-with-auto-update-changed-files-example/
#eigil metioned addResources config for maven build. I'm using spring-boot-gradle-plugin in a gradle build, and I found this Spring Boot github issue
, and the Spring Boot doc mentioned this option too. Just add this directive to build.gradle and run Gradle task bootRun, then resource file refreshes immediately when saved. FYI.
I had the same issue , the solution proposed here seems logical and worked for me
in breif :
1- ctrl+shift+A
2- search for registry
3- in the opened dialogue search for "compiler.automake.allow.when.app.running"
and check it
http://garywaddell.com/2015/11/20/spring-boot-intellij-idea-not-reloading-static-content/
For eclipse you have to activate the Project -> "Build Automatically" option as a minimum configuration.
What I ended up using was Browsersync with grunt. browsersync and grunt watches your static resources on disk and updates the browser when you edit the files. It acts as a kind of proxy. This way you can see changes in UI immediately without building or restarting anything.
Grunt, browsersync, spring boot and angularjs are configured for you if you use JHipster which I used to setup my project.
Granted this requires a lot more tools than just an IDE and is a lot more complicated so I wouldn't recommend this for every project.
spring-boot-devtools is not the solution to "hot deploy" of edited static htm/js
I configured a web facet inside intellij so that when I use it to edit html/js file inside resources/static, intellij then knows to copy the updated file to ./target and the spring boot application I have launched inside the automatically displays that content
see
https://www.jetbrains.com/help/idea/2016.2/configuring-static-content-resources.html
The Java version of #viator 's answer:
#Configuration
class WebMvcConfigurer extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/dist/*.js").addResourceLocations(
"file:src/main/typescript/dist/"
);
}
}
You can do it by just adding one more dependency
you Gradle
compile group: 'org.springframework.boot', name: 'spring-boot-devtools', version: '1.3.0.RELEASE'
In you Pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>1.3.0.RELEASE</version>
</dependency>
You have two possebilities how to serve static webcontent
From the classpath (per default src/main/resources/static
or src/main/resources/public or META-INF/resources/)
From the file system (per default src/main/webapp)
If you pick solution 1) - you can safely copy the jar around as the static web content is within that jar. If you want that the server picks up changes, you need to do (auto)hotswapping.
If you pick solution 2) - everything will work out of the box, every change will be automatically picked up. HOWEVER - if you copy the final jar to a different location - things will stop working. That is unless you specify an absolute path in application.properties. For example:
spring.resources.static-locations=file:///C:/myspringbootapp/src/main/webapp
So solution 2) is easier but less portable. Solution 1) is portable but more difficult to use(ide config).
For Spring Boot 2+ with gradle Kotlin dsl:
tasks.bootRun {
sourceResources(sourceSets.getAt(SourceSet.MAIN_SOURCE_SET_NAME))
}
thanks to #briskr's answer for the gradle dsl version :)
I had the same problem with live reloading of static contents in my SpringBoot porject: Now from various solutions posted in StackOverflow, I am able to get the solution. Following are the tools I used for development: IntelliJ Idea & Google Chrome in Ubuntu 18.04
I did the following:
Kept the templates folder in resourses folder itself. (Some solutions I found it to be kept in webapp folder under the main, but I did not get the result)
Add this configuration
<addResources>true</addResources>
</configuration>
to spring-maven-plugin in your POM file.
3.Please don't forget to add this dependency to POM file
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
Add the Live Reload extension to your web browser.
Restart the server using ' mvn clean spring-boot:run ' (only then the changes will be reflected in the build). During server startup you can see the message Live Server started at ....
Load the page using localhost:8080/... and click the LiveReload extension to connect it with the server.
Make any change to your static HTML file in the resources/ templates folder. Save it and check the webbrowser again, it will be reflected there...

Categories

Resources