I am trying to run a simple web application with using Spring Boot but there is a problem with resolving view. When I go to http://localhost:8080/ it shows;
There was an unexpected error (type=Not Found, status=404).
Is there any missing property or library? Why it cannot resolve my html page?
My application.properties;
spring.mvc.view.prefix: WEB-INF/html/
spring.mvc.view.suffix: .html
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
#Controller
public class InfoController {
#RequestMapping("/")
public String getServerInfo(Map<String, Object> model){
//This method works without any problem.
model.put("message", "server info");
return "info";
}
}
If you use spring boot with some template engine, for example, thymeleaf. You don't need to set spring.mvc.view.prefix or spring.mvc.view.suffix by default.
You just need to put your template files under the directory src/main/resources/templates/:
And your controller will be something like:
#GetMapping("/temp")
public String temp(Model model) {
model.addAttribute("attr", "attr");
return "index";
}
If you are NOT using any template engine and just want to serve HTML page as static content, put your HTML files under the directory src/main/resources/static/:
And your controller will become:
#GetMapping("/test")
public String test() {
return "test.html";
}
if you are using thymeleaf for spring boot. just add below to pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
Try create tree of files like in here.
src/main/resources/static
or
src/main/resources/templates/ //here put html files
putting in here worked for me in a spring-boot web sample:
src/main/webapp/index.xhtml
then in the browser enter:
http://localhost:8080/index.html
here is a linkt to the sample:
https://www.logicbig.com/tutorials/spring-framework/spring-boot/boot-primefaces-integration.html
Related
I used IntelliJ to create a web application with Spring boot which runs on Tomcat using Mustache and Gradle.
My TestController.java and TestApplication.java are in the same package (com.example.test).
Here is the TestApplicaiton.java
#SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
Here is the TestController:
#Controller
public class TestController {
#GetMapping(value = "/")
public ModelAndView index(#RequestParam(name="name", required=false, defaultValue="World") String name, Model model) {
return new ModelAndView("index");
}
}
I put the index.html under both /resources/static and /resources/templates. Still, the page says
404 not found (Whitelabel Error Page).
If I change the #controller annotation to #RestController and change the return type to String, it returns the string properly.
So, it seems like something went wrong when resolving the view. However, it doesn't throw an exception. I noticed that mvContainer view is null when I stepped into the code.
Can someone help?
I think you need to configure ViewResolver to resolve view by name.
Here is a guide: https://www.baeldung.com/spring-mvc-view-resolver-tutorial
For me, I finally found out that I should rename the file extension to .mustache instead of using .html. This will work with the out of the box configuration. Here is an example code I found online:
https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-web-mustache
I have not found out the exact way to override the template path and file extension while having the app still recognize it is a mustache template. So, it will compile before returning it.
I tried to create a simple spring boot application
I created spring boot application class, configuration class, controller class and the index.html.
I added Thymeleaf dependencies and put html page under resources folder (\src\main\resources\templates\index.html)
But when I run the application it gives an error
org.thymeleaf.exceptions.TemplateInputException:
Error resolving template "index.html", template might not exist or might not be accessible by any of the configured Template Resolvers
Please give me a solution.
#SpringBootApplication
#ComponentScan(basePackages = {"com.mail"})
public class SpringBootWebApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootWebApplication.class, args);
}
}
Controller class
#RestController
public class IndexController {
#RequestMapping(value="/", method = RequestMethod.GET)
String index(){
System.out.println("..............hit");
return "index";
}
WebConfiguration for Thymeleaf
#Configuration
public class WebConfiguration extends WebMvcConfigurerAdapter{
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index.html");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
}
index.html page
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head lang="en">
<title>Spring Framework</title>
</head>
<body>
<h1> Hello Spring Boot </h1>
</body>
</html>
Try to do the following:
Replace #RestController by #Controller;
I think you don't need WebConfiguration; the controller returns “index” which means “render the index.html template”. Thymeleaf will find the template in the resources/templates folder.
Try replacing #RestController with #Controller. I would start from the template generated by start.spring.io. And incrementally add functionalities one step at a time.
Or
If you just do some googling, you will be easily able to find some sample thymeleaf projects that actually works, start from there.
Looks like static resources are not accessible by default. Try to provide access to static resources adding resource handler, something like:
#Configuration
public class StaticResourceConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("");
}
}
As described by previous answers, #RestController should be replaced with #Controller.
When we use #RestController, return statement value will be sent as String Response. But when we use #Controller the return statement value will be considered as the view to be rendered.
Refer Diff. b/w #RestController and #Controller
Also, Spring Boot will automatically look for index.html in '\src\main\resources\templates\' which is the default location for views in Spring Boot when we are using Template Engines like Thymeleaf. Refer Spring Boot and Template Engines.
Hence we do not need to explicitly define WebConfiguration class because then we're required to define view-resolvers that are configured in the XML file or in Java class using ViewRegistry. Spring Boot eliminates the need for both this XML and Java View Registry. So you can also do away with WebConfiguration class.
Read point number 2 here.
Add the following dependency in your pom:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
I have a Spring Boot web application, using embedded Tomcat + Thymeleaf template engine, and package as an executable JAR file.
Technologies used :
Spring Boot 1.4.2.RELEASE,
Spring 4.3.4.RELEASE,
Thymeleaf 2.1.5.RELEASE,
Tomcat Embed 8.5.6,
Maven 3,
Java 8
I want to access an static file located in ../src/main/resources/templates/mockups/index.html
so I created this controller:
#Controller
public class MockupIndexController {
#RequestMapping("/mockup/index")
public String welcome(Map<String, Object> model) {
return "/mockups/index.html";
}
}
but I got this error:
org.thymeleaf.exceptions.TemplateInputException: Error resolving template "/mockups/index.html", template might not exist or might not be accessible by any of the configured Template Resolvers
In spring xml configuration file, map your static files location, please keep static files in different folder
<mvc:resources mapping = "/mockups/**" location = "/src/main/resources/templates/mockups/" />
Changes this line
return "/mockups/index.html";
to
return "redirect:/mockups/index.html";
If you are not using config file then add this class
#Component
class WebConfigurer extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/mockups/**").addResourceLocations("/src/main/resources/templates/mockups/");
}
}
I work on spring boot 1.3.3.RELEASE with JSP as view technology.
JSP pages , static resources like CSS, JS and images are loading properly. But how to serve static resource like txt or xml (robots.txt, sitemap.xml)
My controller is handling the request and trying to render jsp view.
Application.java
#SpringBootApplication
public class SampleWebJspApplication extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(SampleWebJspApplication.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleWebJspApplication.class, args);
}
}
Controller
#Controller
public class WelcomeController {
#RequestMapping(value = "/{name}")
public String welcome(#PathVariable String name) {
return name;
}
}
application.properties
spring.mvc.view.prefix: /WEB-INF/jsp/
spring.mvc.view.suffix: .jsp
Following URL's handled by controller and it renders home.jsp
/home
/home.css
/home.js
/home.txt
/home.xml
Following URL's Not working
/home.jsp - 404
/robots.txt - 404 - trying to render robots.jsp
/sitemap.xml - 404 - trying to render sitemap.jsp
Spring-Boot doesnt do jsp's anymore, they are trying to force you to use thymeleaf or another templating engine, static resources are available from certain directories. /static is one of them. and the thymeleaf files need to be in a templates folder.
My setup on my latest spring boot is as follows
application/src/main/resources/static
/templates
application.properties
for other ones you need to add a resourcehandler for the other locations /robots.txt etc
Jsp still works with spring boot.
Not sure if you already did this but its important that you add these dependencies to your maven or gradle.
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
You have configured the Spring's View Resolver with this line spring.mvc.view.prefix , so every response returned by your controllers , will be chained to the view Resolver , which will try to find the resource under /WEB_INF/JSP based on the string name you returned(not sure if you have placed this folder under resources , as your app is a spring boot one , not a java web app). In order to do that and keep the view resolver , either wire up another servlet to share static resources or wire up a ResourcesController with default locations. Something like :
#Configuration
public class StaticResourceConfiguration extends WebMvcConfigurerAdapter {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
"classpath:/myStaticResources/", "classpath:/static/" };
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS);
}
}
More info here or here
Also Spring boot gives you this way as well :
spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/
More info about the application properties here
I'm trying to make "hello world" application with gradle, spring boot and spring mvc with the simplest view resolver and html.
I started from the thymeleaf spring boot example and I just wanted to remove thymeleaf to make a simpler mvc application using pure html and InternalResourceViewResolver. I have a single greeting.html I want to serve which is located at src/main/webapp/WEB-INF. When I run the app I get
No mapping found for HTTP request with URI [/WEB-INF/greeting.html] in DispatcherServlet with name 'dispatcherServlet'
This is a common error and there are a lot of answers on the web but nothing seems to help.
Here is my Application.java
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Here is my GreetingController.java
#Controller
public class GreetingController {
#RequestMapping("/greeting")
public String greeting() {
return "greeting";
}
}
Here is my MvcConfiguration.java
#Configuration
#EnableWebMvc
public class MvcConfiguration extends WebMvcConfigurerAdapter{
#Bean
public ViewResolver getViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/");
resolver.setSuffix(".html");
return resolver;
}
}
I run it with gradle bootRun
Here is the repo with the code: https://github.com/driver-pete/spring-mvc-example
Here are some more clues:
Thymeleaf view resolving works fine
InternalResourceViewResolver resolves to the right path
WEB-INF and greeting.html seems to be present in the war file
I do not have jsp or jstl so I do not miss those jars as some might suggest
My hypothesis is that dispatcher servlet somehow get configured to serve on /* instead of / like here and everywhere. However I don't have web.xml so those advices do not apply here. I see a lot of examples how to configure dispatcher servlet programmatically but I want to keep my app at minimum and I suspect that spring boot is supposed to configure it ok since it works fine with thymeleaf.
You only need to enable the default servlet, this is done by adding the following to your MvcConfiguration:
#Configuration
#EnableWebMvc
public class MvcConfiguration extends WebMvcConfigurerAdapter{
#Bean
public ViewResolver getViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/");
resolver.setSuffix(".html");
return resolver;
}
#Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
Essentially what is happening is Spring does not know how to handle the handling of such content natively(could be a jsp say), and to this configuration is the way to tell it to delegate it to the container.
View resolver can also be configured in application.properties file of Spring-Boot web applications, something like below:
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
After investigating more I discovered an alternative solution that works without adding configureDefaultServletHandling method. You need to add an embedded tomcat jsp engine to build.gradle:
compile("org.apache.tomcat.embed:tomcat-embed-jasper")
As opposed to configureDefaultServletHandling method this solution works not only with plain html but also with jsp.
All solutions are available at: https://github.com/driver-pete/spring-mvc-example
This solution is available on master.
Biju's solution is on DefaultServletHandling_solution branch.
If you are using spring above 5.0, then use org.springframework.web.servlet.view.InternalResourceViewResolver
instead of
org.springframework.web.servlet.InternalResourceViewResolver
in your bean definition