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/");
}
}
Related
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
I am using Spring Boot as an API and Angular as the frontend for my Application. I build with Maven and so configured the frontend-maven-plugin so it copies all the Angular dist folder into the final jar when building.
What I would like to have is all of my controllers' mapping to have a prefix like '/api' so it becomes '/api/users', but also that my static resources mappings stay what they are, like only '/sign-up' instead of '/api/sign-up'.
So I searched for the server.context-path and server.servlet-path properties but none of them worked. Anyone can help me please ?
#Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
#Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.addPathPrefix("/api",
HandlerTypePredicate.forAnnotation(RestController.class)
.and(HandlerTypePredicate.forBasePackage("com.company.api")));
}
}
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 have a Spring Boot web application that adds a resource handler for static resources (mainly CSS and JS files) using the addResourceHandlers method of WebMvcConfigurerAdapter. This resource handler is further configured to enable a VersionResourceResolver Basically this is
public class CustomWebMvcConfigurer extends WebMvcConfigurerAdapter {
...
#Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
ResourceHandlerRegistration registration = registry.addResourceHandler(...)
ResourceChainRegistration chainRegistration = registration.resourceChain(...);
chainRegistration.addResolver(
new VersionResourceResolver().addContentVersionStrategy(...));
...
}
}
Now the problem is, when the user sees an error page (for example the 404 page), this VersionResourceResolver won't be used. (The error pages are configured using #ExceptionHandlers in a #ControllerAdvice annotated class.) The error pages will be rendered and displayed fine, however, the resources loaded on this page don't have version applied.
The Spring Boot documentation has a note saying that an ERROR dispatcher needs special treatment, however, I cannot figure out how to apply this advice in the context of our WebMvcConfigurerAdapter.
Any help is appreciated.
I had the same problem in a my opensource project and I resolve in this way.
I create an #Controller class like this:
#Controller
public class ExceptionController {
#Autowired
private MessageSource messageSource;
public void setMessageSource(MessageSource messageSource) {
this.messageSource = messageSource;
}
#RequestMapping("/exception")
public String exception(Model model,Exception ex,Locale locale,HttpServletRequest httpRequest,HttpServletResponse httpResponse){
ex.printStackTrace();
model.addAttribute("templatePath", "exception/exception");
model.addAttribute("template", "content");
try{
model.addAttribute("exceptionMessage",messageSource.getMessage(String.format("exception.body.%s",httpResponse.getStatus()),new Object[]{},locale));
} catch (NoSuchMessageException e){
model.addAttribute("exceptionMessage",messageSource.getMessage("exception.body",new Object[]{},locale));
}
return "index";
}
}
and then I customize the servlet container configuration in this way:
#Bean
public EmbeddedServletContainerCustomizer exceptionHandling() {
return container -> container.addErrorPages(new ErrorPage("/exception"));
}
in feew words I make a special page for error /exception in this case and then configure the embedded tomcat for use this url in case of exceptions
In the Autoconfiguration classes of Spring boot you can see in org.springframework.boot.autoconfigure.web.BasicErrorController this documentation:
Basic global error {#link Controller}, rendering {#link ErrorAttributes}. More specific
* errors can be handled either using Spring MVC abstractions (e.g.
* {#code #ExceptionHandler}) or by adding servlet
* {#link AbstractEmbeddedServletContainerFactory#setErrorPages container error pages}
I hope that tis can help you
Background
I have a spring boot application which has the logo.png file added to the static folder of the resource file, which is eventually built into the jar file which is used in the execution.
This jar application need to be run in multiple instances for different clients. So what I did is create an external application.properties file which distinguish the settings for each users.
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
Problem
But the problem is, i need to change the logo of each instance of my application. I cannot embed the customer logos into my application jar. Rather I need to keep it external like my application.properties.
For the moment, what I have done is check for the file logo.png in the same folder of jar of execution, and if excist, read the file, get base64 data and show it in the img tag.
But I want this to be done in a proper way as static content. I need the static content to be externalized. so I can let each customer have a specific instance of the jar running with different static resource content
For example. I need to keep the external static files as below and access from the urls in my view href or src attributes of the html tags.
Summary
Required folder structure
+ runtime
- myapp-0.1.0.jar
- application.properties
+ static
- logo.png
Should be able to access
<img th:src="#{/logo.png}" />
You can use resource handlers to serve external files - e.g.
#Component
class WebConfigurer extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/ext/**").addResourceLocations("file:///yourPath/static/");
}
}
The WebMvcConfigurerAdapter is deprecated. As from Spring Boot 2.x you could use WebMvcConfigurer instead.
#Configuration
public class MediaPathConfig {
// I assign filePath and pathPatterns using #Value annotation
private String filePath = "/ext/**";
private String pathPatterns = "/your/static/path/";
#Bean
public WebMvcConfigurer webMvcConfigurerAdapter() {
return new WebMvcConfigurer() {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!registry.hasMappingForPattern(pathPatterns)) {
registry.addResourceHandler(pathPatterns)
.addResourceLocations("file:" + filePath);
}
}
};
}
}