I am trying to display an image on a jsp page.
I am developping using spring security/mvc.
this is the part of jsp page :
<a href="/images/logo.png">
<img src="/images/logo.png" alt="logo">
</a>
and this is the configuration :
#Configuration
#EnableWebMvc
#ComponentScan(basePackages ="...")
public class HelloWorldConfiguration extends WebMvcConfigurerAdapter {
#Bean(name="HelloWorld")
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
/*
* Configure ResourceHandlers to serve static resources like CSS/ Javascript etc...
*
*/
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("/static/");
registry.addResourceHandler("/images/**").addResourceLocations("/images/");
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
when I run the image doesn't display.
I tried a lot of suggestions none of them worked, I also tried relative and absolute paths.
Surely the problem is your file structure.
Open the developer tools using CTRL+SHIFT+I (in Mozilla or Chrome) and inspect the image element. Surely the link is broken meaning that you are trying to source the images from the wrong location (or a non-existing one).
Use the context path:
<img src="${pageContext.request.contextPath}/images/logo.png"/>
According to your configuration your image should be in the root of the web app in the child folder images/logo.png. Your img tag should include the servlet context root. You should append the context root for example using jsp core tag library
<c:url value="/images/logo.png" var="logo"/>
<a href="${logoUrl}">
<img src="${logoUrl}" alt="logo">
</a>
NB. The method to append the context depends on the rendering technolgy. If you are using plain HTML you can append the context root manually. However this hardcodes the value and is a maintance nightmare as you need to change the value in every page when you need to change the context
<a href="/myapp/images/logo.png">
<img src="/myapp/images/logo.png" alt="logo">
</a>
try using relative path to your image:
<a href="../../images/logo.png">
<img src="../../images/logo.png" alt="logo">
</a>
Related
I have webproject which has images inside src/main/webapp folder. I would like to place images in different folder on the disk. But I have no idea how to manage requests to reach this images.
Should I create some kind of httpServlet like shown here: http://balusc.omnifaces.org/2007/07/fileservlet.html
Or as I use Spring MVC with java configuration, there is more suitable and simpler way.
Looking forward for your suggestions.
Use the spring mvc support for static resources, its location attribute is an Spring Resource, so you could use file: prefix
<resources mapping="/resources/**" location="file:/my/external/directory/" />
or
#Configuration
#EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("file:/my/external/directory/");
}
}
#See Spring Reference Chapter 6.4 The ResourceLoader for a table that list all prefixed for resources
In my case I placed js and css resources in webapp and images in e://images/.
For this case I use two mvc:resources mapping
<mvc:resources mapping="/resources/**" location="/resources/"/>
<mvc:resources mapping="/images/**" location="file:e://images/"/>
And locate the image of e: > images > abc.jpg using ....
<img src="../images/abc.jpg"/>
You could try also <img src="/images/abc.jpg"/> or <img src="images/abc.jpg"> (If not work)
The css/js linked under webapp > resources > js > xyz.js like below.
<script type='text/javascript' src='../resources/js/xyz.js'></script>
You canimplement WebMvcConfigurer in your main Application or Main class.
#SpringBootApplication
#ComponentScan("com.your.package.controller")
#Configuration
public class ServicesApplication implements WebMvcConfigurer { // ServicesApplication is my main class
String your_drive_location = "file:///D:/upload_dir/upload/"; // my file path
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/images/**").addResourceLocations(your_drive_location );
}
public static void main(String[] args) {
SpringApplication.run(ServicesApplication.class, args);
}
}
I am using JSTL for showing:
<c:forEach items="${ListOfBrand}" var="brand"> // ListOfBrand is a Map
<img src=" <c:out value="/images/"/>${brand.brand_image}" /> // Showing all image from brand table
</c:forEach>
Currently, I have my main page rendered by the thymeleaf resolver server-side, so tags such as
<span th:text="#{userId}"></span>
works properly. However, when I load a partial page using angular's ng-route and routeProvider like
$routeProvider.
when('/c1000', {
templateUrl: 'pages/C1000.html'
});
and in my C1000.html, I have a tag such as
<span th:text="#{userId}"></span>
It does not display. I am assuming it's because the main page is resolved by thymeleaf's resolver while the partial is loaded as an ordinary HTML file. I have implemented internationalization so the text for #{userId} changes language based on the properties file. What I want is for the partial page to also display #{userId} similar to how my main page displays it. Is there a way to do this?
I'm passing a bean QuoteOption into the model that has a method called getCachedImageUrl(url, width, height) that returns a URL for the image.
My Thymeleaf template:
<img th:src="${quoteOption.getCachedImageUrl(baseUrl,300,200)}" />
Generates
<img src="http://nitro:8080/image/nitro-resources-development/28f08e67-96c9-4bb4-8012-9e34040cc976.jpeg?width=300&height=200" />
Notice the & in the url parameters! Aaaargh! How do I instruct Thymeleaf to not escape the ampersand?
Bean with name someBean:
public class SomeBean {
public String testMethod() {
return "http://nitro:8080/image/nitro-resources-development/28f08e67-96c9-4bb4-8012-9e34040cc976.jpeg?width=300&height=200";
}
}
In Thymeleaf :
<img th:src="${#applicationCache.testMethod()}" id="_Bhuwan"/>
<button onclick="alert($('#_Bhuwan').attr('src'))">See</button>
Two Case :
In alert Show message as :
http://nitro:8080/image/nitro-resources-development/28f08e67-96c9-4bb4-8012-9e34040cc976.jpeg?width=300&height=200
In View Page Source or Edit HTML in Browser. Generate :
<img src="http://nitro:8080/image/nitro-resources-development/28f08e67-96c9-4bb4-8012-9e34040cc976.jpeg?width=300&height=200">
So that actual value in src attribute of img tag is http://nitro:8080/image/nitro-resources-development/28f08e67-96c9-4bb4-8012-9e34040cc976.jpeg?width=300&height=200 in this case. But when we try see value using View Page source or edit html through browser then Browser may escape & char to &.
Tested On
Themeleaf version is 2.1.4.RELEASE in Spring 4.
First to say is that I've been searching for a solution for a while now and I'm quite desperate now.
I cannot get the css file to be accessible from html page when run by Spring Boot.
html.file
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head lang="en">
<title th:text='#{Title}'>AntiIntruder</title>
<meta charset="UTF-8" />
<link rel="stylesheet" type="text/css" media="all" href="../assets/css/style.css" th:href="#{/css/style.css}" />
</head>
<body>
...
Application.java
#SpringBootApplication // adds #Configuration, #EnableAutoConfiguration, #ComponentScan
#EnableWebMvc
public class Application extends WebMvcConfigurerAdapter {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/assets/**").addResourceLocations("classpath:/assets/*");
}
}
folder structure:
I've tried putting the css folder into a static folder and/or removing the addResourcesHandlers, referencing to the css by relative path and some other things. Nothing seems to resolve this.
Please, let me know also if you tried to solve this but did not find a solution, so that I know, that I'm not ignored.
1. Using Custom Resource Path
In your Web Config
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!registry.hasMappingForPattern("/assets/**")) {
registry.addResourceHandler("/assets/**").addResourceLocations("classpath:/assets/");
}
}
Put your style.css file inside this folder
src/main/resources/assets/css/
After that in your views
<link rel="stylesheet" type="text/css" th:href="#{/assets/css/style.css}" />
.
2. Using predefined paths in spring boot
Remove addResourceHandlers from your web config
Put the style.css inside any of the following folders
src/main/resources/META-INF/resources/assets/css
src/main/resources/resources/assets/css/
src/main/resources/static/assets/css/
src/main/resources/public/assets/css/
And in the view
<link rel="stylesheet" type="text/css" th:href="#{/assets/css/style.css}" />
.
NOTE: You can remove the assets folder here. If you want to do it, remove it from the predefined resource folder and also from the view th:href. But i kept it as it is because, you explicitly mentioned the assets/ path in your question. So I belive it's your requirement to have assets/ in your resource URL.
The problem was the #EnableWebMvc annotation in the Application.java file. As soon as I removed that one, the css started to be available at localhost:8080/css/style.css but was not applied. So far I haven't found the reason why the #EnableWebMvc was causing the problem.
Then I removed a controller mapped to /** that I had implemented in order to display custom error page.
#RequestMapping("/**")
public String notFound() {
return "errors/404";
}
After removing also this one, I've got my css working. =)
If you put your css in the static folder, you dont need the addResourceHandlers method.
.../static/css/app.css
Or if you really want to put them in the assets folder:
.addResourceLocations("classpath:/assets/") <-- without the * at the end
.../assets/css/app/css
in both cases the css should be available through
th:href="#{/css/app.css}"
Put your css folder inside resources/static folder
In my case the problem was in file read permissions.
I copied the file 'style.css' from another project, and browser could not read it.
After re-creating 'style.css', everything worked fine.
My advice is to put (again) css folder under static folder, remove addResourcesHandlers and reach css with absolute path (e.g. /css/style.css).
For me I had to remove the static reference to the stylesheet for it to work in thymeleaf.
So
<link rel="stylesheet" type="text/css" media="all" href="../assets/css/style.css" th:href="#{/css/style.css}">
Became
<link rel="stylesheet" th:href="#{/css/bootstrap.css}">
I spent hours trying all sorts of configurations and file path renaming. Don't know why but this is the only thing that got my css and js to load in Spring Boot 5.
first implements on one of your configuration class with WebMvcConfigurer like this
#Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
//and overide this configuration method like this
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/webjars/**", "/resources/**");
}
}
so now you can overide your HttpSecurity configuration like this
#EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter{
#Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/index").anonymous()
.antMatchers("/**/*.*").permitAll()
.anyRequest().authenticated();
}
}
this ("/**/*.*") regex text will allow files with anny extension
and if your are using an webjars libraries like bootstrap add this config to your WebSecurityConfiguration
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
If this topic still relevant in 2022.
I have had a similar problem and i solved it like this:
This link in /templates/file.html
<link rel="stylesheet" type="text/css" media="all" ref="../static/css/styles.css">
and i have added application.properties
spring.mvc.static-path-pattern=/static/**
my css path is
src/main/resources/static/css/
helpful link
I have a spring mvc application, in a page I list the "Group" details in a table, fetched from database. The url of every group is set to "/viewgroup/410", where 410 is the groupid which will be loaded from the database and displayed in the viewgroup.jsp page.
<td>${group.name}</td>
So, the controller method has the
#RequestMapping("/viewgroup/{groupid}")
public String viewGroup() {
...
}
like this. The jsp pages could not load the static resources which I have in the directory structure
+webapp
+resources
+css
+js
+images
+views
+login.jsp
The jsp pages has the below path for image/js/css.
<link href="resources/css/bootstrap.css" rel="stylesheet" media="screen">
I tried adding
#Controller
#RequestMapping("/viewgroup/**")
public class ViewGroupController {
...
}
and this in jsp
<link href="viewgroup/resources/css/bootstrap.css" rel="stylesheet" media="screen">
Still the jsp page loads could not load the static resources. How do I provide the resource path of the static resources in jsp pages when I pass params in the url?
The fact that you pass query parameters through any URL of your project does not affect the way it addresses static resources. You need just to include a link to your static resources (as a relative path for example) as follow :
<link href="/resources/css/bootstrap.css" rel="stylesheet" media="screen">
The resolution of such static resources is completely independent of the page you're currently looking at, be it /viewgroup/410 or /foo/bar. That's the reason why you don't need the "viewgroup" at the beginning of your link's href.
But you do need to tell Spring MVC how it should address such static resources. Usually, this is done in the Spring configuration. For example, if you use Spring MVC java config through an WebMvcConfigurer instance, you should override the addResourceHandlers method in such way :
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
EDIT : My bad, I thought Spring MVC + any view technology (JSP, Thymeleaf, etc etc) would automatically resolve link's href against the root path of the web-app but this is obviously not true to raw HTML which relative link's href are resolved against current path.
So in the end, as found by OP, links are only to be resolved against root path if they are processed with the view technology in use (in the example with JSP : <c:url value="/resources/css/bootstrap.css"/>)