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"/>)
Related
My root URL keep messing up in the Spring MVC application. I have the following resource defined in servlet-context.xml
<!-- Resource Mapping -->
<resources mapping="/theme1/**" location="/resources/theme1/" cache-period="31556926"/>
On the header of localhost:8080/me/login.jsp I have the following CSS file
<link rel="stylesheet" href="theme1/css/main.css" type="text/css"></link>
Now on the same JSP, I have an anchor text register which maps to /useraccount/register.T
The method in my controller returns the same view, login.jsp. So after a page refresh, the domain is changed to localhost:3000/me/useraccount/register
So the problem is that style sheet URL becomes invalid - return 404. It now points to
localhost:8080/me/useraccount/theme1/css/main.css
How do can I fix this so it points back to - in a sense being static - to
localhost:8080/me/theme1/css/main.css
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
How may I serve two assets folder for the same URI in Dropwizard. Currently only the first one is being served, when using the same name for URI.
I'm registering AssetsBundle using (in my main application class):
public void initialize(Bootstrap<DummyFrontendConfiguration> bootstrap) {
bootstrap.addBundle(new AssetsBundle("/assets1", "/public", null, "assets1"));
bootstrap.addBundle(new AssetsBundle("/assets2", "/public", null, "assets2"));
bootstrap.addBundle(new ViewBundle());
}
Css file (main.css) in assets1:
h2{
color: red;
}
Css file (main2.css) in assets2:
h4{
color: green;
}
In html template head:
<link rel="stylesheet" type="text/css" href="public/stylesheets/main.css">
<link rel="stylesheet" type="text/css" href="public/stylesheets/main2.css">
In html template body:
<h2>This should be red</h2>
<h4>This should be green</h4>
Unfortunately the second css file (main2.css) couldn't be loaded during the html page rendering (404 - not found), any ideas?
The assets module isn't designed to function this way. Under the hood it's calling:
environment.servlets().addServlet(assetsName, createServlet()).addMapping(uriPath + '*');
Both servlets can't be mapped to the same path. You could fix this by switching one of the "public" mappings to be another path ("public2", for instance).
If you indeed need to keep your resources completely separate you may want to consider introducing another step in your build (via maven or ant) that merges the assets into a single directory structure for deployment.
I have a web application deployed inJava using Struts 1 as the the MVC library.
I am required to provide different CSS/Images folders based on the selected language.
I already have WebMessageResources.properties configured with 4 different languages.
One approach I took is to define to the root path of the CSS/Images folder in the message resources.
However, I'm finding this to be somehow "dirty" and requiring changes all over the code.
For example, in one my JSP pages, I was forced get the path using JSP tags than concatenate the string in the css href.
MessageResources mres =
MessageResources.getMessageResources(Constants.RESOURCES_BUNDLE);
Locale locale = (Locale)
pageContext.getSession().getAttribute(Globals.LOCALE_KEY); String
langResources = mres.getMessage(locale, "path.resources");
....
<link rel="stylesheet" type="text/css" href="<%= langResources %>css/styles.css" />
Is there a better "out of the box" way to do this? I'm not very familiar with Struts.
struts has inbuild support for i18n. See this
http://www.mkyong.com/struts2/struts-2-i18n-or-localization-example/
http://exadel.com/tutorial/struts/5.2/strutstutorials-i18n.html
From a servlet, I'm forwarding the request to a JSP page which renders a FusionChart.
But I've a problem in loading the chart. The JSP file is not detecting the JavaScript file. The folder structure is:
axis
|
WebContent
|
WEB-INF
|
classes
|_ com
|_FusionCharts.js
|_MyChartJsp.jsp
|_Line.swf
And the JSP code:
<html>
<head>
<script language="text/javascript" src="/WEB-INF/classes/FusionCharts.js"></script>
</head>
<body bgcolor="#ffffff">
<div id="chartdiv" align="left">The chart will appear within
this DIV. This text will be replaced by the chart.</div>
<script type="text/javascript">
var foo = //value fetched from DAO
var myChart = new FusionCharts("/WEB-INF/classes/Line.swf",
"myChartId", "1000", "500");
myChart
.setDataXML("<graph caption='aCaption' xAxisName='xAxis' yAxisName='yAxis' showNames='1' decimalPrecision='0' formatNumberScale='0'>"+foo+"</graph>");
myChart.render("chartdiv");
</script>
</body>
</html>
The Servlet code to forward the request:
final RequestDispatcher requestDispatcher = request.getRequestDispatcher("/WEB-INF/classes/MyChartJsp.jsp");
requestDispatcher.forward(request, response);
The request is getting forwarded to the JSP. But the chart is not getting displayed because it is unable to figure out what FusionCharts is in the line
var myChart = new FusionCharts("/WEB-INF/classes/Line.swf",
"myChartId", "1000", "500");
I tried
src="/FusionCharts.js"
src="FusionCharts.js"
but no luck.
Has it something to do with the request being forwarded??
You cannot have .js (or .swf, .jpg, etc.) files in WEB-INF - they are not publically accessible.
Move it to /js/
There is no reason to hide static resources (like scripts and css) in WEB-INF. If you insist on that, you should make a servlet that, given the name of the js/css, would read it from its location and will serve it as a response. This is what the default servlet does when you access static resources.
The flow of the page loading is as follows: the browser sends a request to the servlet; the servlet forwards internally to the JSP, and the JSP is rendered as a response; then the browser parses the <script> tag and fires another request to the script. If the script is not accessible via URL, it's not loaded.
Then, to make the script url fixed to the servlet context root, use
src="<c:url value="/js/script.js" />"
This will work regardless of what is the current url
Not the cause of your problem, but also note that your <script> element is incorrect. It should be <script type="text/javascript"....
(I tried to post this as a comment, but for some reason it wouldn't let me.)
I was facing same issue. In my case when I calling the myFile.jsp directly its reading the myFile.js;
But when calling through login-> myFile.jsp, its not reading the myFile.js;
After analyzing the path through the Developer tools :=> console, I found that its inserting the uri, so final path was incorrect.
Final Solution:
I'd used the absolute path for all .js and .css. Now its called from everywhere.
My Project Structure is:
In my servlet-context.xml
i) <context:component-scan base-package="com.SBP.SHWeb" />
ii) <resources mapping="/resources/**" location="/resources/" />
My old path for including .js was: /resources/MyJs/myfile.js ===> Its not get called sometimes.
My Absolute path, which get called from all places is like this:
/SHweb/resources/MyJs/myfile.js ==> Its get called from everywhere.
Hope it help you.