Spring boot cannot find index.html under webapp folder - java

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.

Related

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.

External static html view resolver + thymeleaf

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.

Static web resources in Spring Boot + Spring Security + Thymeleaf

I'm trying to make Spring Security permit access to static resources to all users, but for now nothing works.
When I used jsp in previous project, the solution was simple:
http
.authorizeRequests()
.antMatchers("/static/**").permitAll()
.anyRequest().authenticated()
Static folder was placed inside webapp folder which was the root folder and was easily detected by Spring Security. Now, because of Thymeleaf, there is no webapp folder and all the static folders are placed into src/main/resources. I have no idea, how to create antMatcher for something that is inside resources folder... I tried that:
http
.authorizeRequests()
.antMatchers("resources:/static/**").permitAll()
.anyRequest().authenticated()
It never worked. What is the solution?
ps. I have seen a statement that Spring Boot + Spring Security allows this intra-resources access by default, but it does not.
The solution is found. For my folder structure src/main/resource/static/css I should have used
.antMatchers("/css/**").permitAll()
instead of
.antMatchers("/static/**").permitAll()
Check my answer there: Spring boot mapping static html
Basically you have to add resource handlers by extending WebMvcConfigurerAdapter to map http://yoursite/static_url_prefix to your static_app_dir directory in your resources directory.
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static_url_prefix/**").addResourceLocations("classpath:/static_app_dir/");
super.addResourceHandlers(registry);
}
This will intercept all request coming to http://yoursite/static_url_prefix and return results from classpath://static_app_dir in your jar file or from /resources/static_app_dir when running application from your IDE.
Spring security can be configured as before as it has nothing to do with it i.e. your first code example seems correct.

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.

Dynamic Web Application - platform with components

I am doing a research on how to make a proper structure for my web application.
It will be a web application serving as a platform for additional, independent components.
The components must be able to map requests by using the #Controller annotaion.
So far I have learned, that:
The platform will be deployed as a .war file on Tomcat.
The platform classpath location will contain components in a form of .jar files.
My question is:
How to setup the components and the platform, so that platform will make use of the components' #Controllers?
So far I have the platform.war running on Tomcat. It is annotation based Spring configuration.
I also have the first component, it is a single Java class with #Controller annotation and first mapping. For some reason when I include this component in the classpath of the platform and try to access the url mapped in the component, the application returns 404 error. In the log files it says "No mapping found for HTTP request" so it does not initialize the component's #Controller.
For further explanation click here.
In your JAR file, create a package defining your namespace, i.e: "com.platformproject.web". Then all you need to do is put the JAR file in WEB-INF/lib (or better use Maven Modules) and scan the annotations at startup:
MvcConfig.java
#EnableWebMvc
#Configuration
#ComponentScan(basePackages = { "com.platformproject.web" })
public class MvcConfig extends WebMvcConfigurerAdapter { ... }

Categories