External static html view resolver + thymeleaf - java

I have a Spring boot project. There are some static HTML (without thymeleaf) and some with thymeleaf. Whenever I configure ResourceHandlers to serve static pages, it works fine to serve them. When I try to add ThymeleafViewResolver the static pages start to fail. Is there a way to create 2 view resolvers - one for thymeleaf othe rone for static htmls exclusive?
Static htmls are placed outside of jar, in an external folder. For thymeleaf it works just fine to put in a path "C:/Users/...", but for resourceHandlers it does not. Adding file:/// (for windows) does not work either.

Related

Spring Boot with custom context path - Cannot access static web files

I have a Spring Boot application (2.2.6.RELEASE) that uses ReactJs as a frontend library.
I have configured in application.properties a custom context-path and spring.mvc properties like so:
server.servlet.context-path=/gui
spring.mvc.view.prefix: /static/dist/
spring.mvc.view.suffix: .html
spring.mvc.static-path-pattern=/static/**
Webpack is used to build bundles and an index.html into src/main/resources/static/dist. Here is how the project structure looks like:
I need to be able to access index.html from
localhost:8080/gui
with these settings but for some reason it does not pick it up. However if I try with
localhost:8080/gui/static/dist/index.html
the resource is reached. How do I configure Spring to serve the resources as I would like to?
#Oleh Kurpiak answer was correct. Using spring.resources.static-locations=classpath:/static/dist/ helped out.

How to configure Thymeleaf template location

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.

Mapping my Spring boot application to a HTML file on local host

I'm trying to link a HTML page to my Spring boot application.
I've connected a SQL DB to it, and have set up the needed controllers, but cannot map the HTML page to the local host.
Here is the GIT for the project.
https://github.com/ThierryLucDenichaud/SpringBoot_SQL_SPRING_HTML.git
Create a configuration file that look like the following:
#Configuration
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("indexPage.html");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
}
This will create a default controller for serving your index.html on /.
A little recommendation, change indexPage.html to index.html and also setViewName("indexPage.html") to setViewName("index.html") as index.html is usually the default in most systems and frameworks.
EDIT
I just noticed your public folder is in src/main while it should be in src/main/resources. spring boot won't handle your static files unless they are first in src/main/resources then in public as the default folder that is exposed to the outside world.
Also in Java you should place classpath resources in src/main/resources or src/test/resources for tests.

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!

Spring boot cannot find index.html under webapp folder

I read the following documentation from spring.io and it said By default Spring Boot will serve static content from a directory called /static (or /public or /resources or /META-INF/resources) in the classpath however when I put my index.html file under /resources the string index is just rendered. Currently index.html is under webapp and I am using AngularJS.
MvcConfiguration
#Configuration
public class MvcConfig {
#Bean
InternalResourceViewResolver viewResolver(){
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/webapp/");
resolver.setSuffix(".html");
return resolver;
}
}
Restful Service for index page
#RestController
public class IndexController {
#RequestMapping("/")
public String index(){
System.out.println("Looking in the index controller.........");
return "index";
}
}
ON my IDE console I do see Looking in the index controller...... printed from IndexController and under network in the Chrome development tools I only see localhost 200.
index.html
<body>
<!--[if lt IE 7]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please upgrade your browser to improve your experience.</p>
<![endif]-->
<div ng-view></div>
<div>Angular seed app: v<span app-version></span></div>
Spring Boot docs also says:
Do not use the src/main/webapp directory if your application will be
packaged as a jar. Although this directory is a common standard, it
will only work with war packaging and it will be silently ignored by
most build tools if you generate a jar.
Spring Boot is very opinionated and works best when you do not try to resist defaults. I don't see any reason having your files placed in /src/main/webapp. Just use /src/main/resources/static for your front-end assets. That is most common place.
It will serve these static files from root URI automatically, without need to create any root level Controller. In fact your IndexController would prevent static front-end files to be served from root URI. There is no need to create Controller for static files at all.
Also view resolver is not needed for your app. Your app is just REST API consumed by single page angular application. So your HTML templating is on client. View resolvers are needed if you are doing server side HTML templating (e.g. with Thymeleaf or JSP). So remove that piece also.
#RestController
public class IndexController {
#RequestMapping("/")
public String index(){
System.out.println("Looking in the index controller.........");
return "index";
}
}
Problem is here, you are using #RestController, so in this case, if you write "return 'index';" spring boot covers it as just string answer. You need use #Controller annotation instead.

Categories