how to use css in jsp pages - java

I am trying to use css file from my jsp pages but page does not see the css codes.
this is my .jsp file;
<html class="no-js" lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Foundation | Welcome</title>
<link rel="stylesheet" href="/sources/css/foundation.css" />
<script src="/sources/js/vendor/modernizr.js"></script>
</head>
<body>
this is my configuratin file
#Configuration
#ComponentScan("com.sprhib")
#EnableWebMvc
public class BaseTestConfig {
#Bean
public UrlBasedViewResolver setupViewResolver() {
UrlBasedViewResolver resolver = new UrlBasedViewResolver();
resolver.setPrefix("/WEB-INF/pages/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/sources/**").addResourceLocations("/sources/");
}
}

The webapp is not deployed as the root webapp. So it has a "context path". The path to access the index.html file which is at the root of your webapp, for example, is in fact something like
http://localhost:8080/myfirstwebapp/index.html
This is what the location bar of your browser contains, and /myfirstwebapp is the context path of your application.
So, if you page contains href="/sources/css/foundation.css", the browser will try to load the css file from
http://localhost:8080/sources/css/foundation.css
and not from
http://localhost:8080/myfirstwebapp/sources/css/foundation.css
You thus need to prepend the context path to all the absolute URLs in your webapp. Using the JSTL:
href="<c:url value='/sources/css/foundation.css'/>"
Without the JSTL:
href="${pageContext.request.contextPath}/sources/css/foundation.css"

Remove the / in /sources. This will work

Try to call those css directly through your web browser with full URL path.
It depends on what's your application path defined in your Tomcat or web server.
If it's mapped like http://yourdomain.com/ ( root ), it should be http://yourdomain.com/sources/css/foundation.css, but if it's mapped like http://yourdomain.com/test or something, URL for CSS should be http://yourdomain.com/test/sources/css/fundations.css.
You may use either relative pass for those, or introduce PATH variable so that link always created like http://yourdomain.com/PATH/sources/css/foundations.css in the source code.

Related

why spring-boot does not access the front-end packaged "dist" static resources?

When I import the files which the front-end developer packages the dist project, and SpringBootApplication run, I can visit index.html, but I can't read its static resources, can't show the pic, it's all black. And index.html source code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="apple-touch-icon" href="./pwa-192x192.png">
<link rel="mask-icon" href="./safari-pinned-tab.svg" color="#00aba9">
<meta name="msapplication-TileColor" content="#00aba9">
<script>
(function () {
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
const setting = localStorage.getItem('vueuse-color-scheme') || 'auto'
if (setting === 'dark' || (prefersDark && setting !== 'light'))
document.documentElement.classList.toggle('dark', true)
})()
</script>
<script type="module" crossorigin src="./static/js/index-d3549438.js"></script>
<link rel="stylesheet" href="./static/css/index-db70e0a5.css">
</head>
<body class="font-sans">
<div id="app"></div>
</body>
</html>
the positions of dist file : resources/dist, and my dist file contains static file.
And my configuration about SpringApplication is in application.yml:
Spring:
web:
resources:
static-locations: "classpath:/dist"
And I also add SpringWebMvcConfig.java in my config-files:
#Configuration
#ComponentScan
public class SpringWebMvcConfig extends WebMvcConfigurationSupport {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/dist/**").addResourceLocations("classpath:/dist/");
}
}
If possible, I would really appreciate it if you could help me point out the problem.
:)
I can visit "index.html" only use npm.
I don't know how to set it up the way you want it, but this is how I do it in my project. I copy the files to the resources folder of the java application. Here an excerpt of my vue.config.js:
const {defineConfig} = require('#vue/cli-service');
module.exports = defineConfig({
outputDir: 'src/main/resources/public/clientlibs/vue-dist'
});
Then you can access these from the spring templates with: /clientlibs/vue-dist/vue-app.js

How do I access style sheets in a library JAR file from a Thymeleaf template?

I have a set of Spring-based, Java web applications and a common framework library made available to them all via a JAR file. I'm using Thymeleaf for the views.
I have a common Thymeleaf template that is used by several of the web applications. The template HTML file and its associated style sheet are both in the library JAR file. When a web application displays a view based on the framework template, the template is found and processed by Thymeleaf.
My problem is that I cannot figure out how to import the style sheet such that it is loaded and passed back to the browser. The end result is un-styled (albeit correct) HTML.
I'm using Gradle as my build tool.
Here's my relevant project structure for the framework:
common-framework/src/main
../java - contains the framework code
../resources - contains the framework resources
../static
../css
example.css - Style sheet for use in templates
../templates
../fwk
example.html - Thymeleaf template
Here's my relevant project structure for an example app:
app/src/main
../java - contains the application code
../resources - contains the application resources
../templates
../app
start.html - Thymeleaf template
../webapp
../resources
../css
app.css - Style sheet for use in the app
Here's the ViewResolver bean that is used by both the app and the framework for locating templates:
#Bean
public ViewResolver viewResolver()
{
ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
templateResolver.setTemplateMode("HTML5");
templateResolver.setPrefix("templates/");
templateResolver.setSuffix(".html");
templateResolver.setCharacterEncoding("UTF-8");
templateResolver.setOrder(1);
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setTemplateResolver(templateResolver);
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(engine);
viewResolver.setCharacterEncoding("UTF-8");
viewResolver.setOrder(1);
return viewResolver;
}
Here's my resource handler configuration (from my WebMvcConfigurerAdapter):
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/resources/**")
.addResourceLocations("/resources/");
}
Here's the framework Thymeleaf template (fwk/example.html)
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8" />
<title th:text="${title}"></title>
<link rel="stylesheet" type="text/css" th:href="#{/resources/static/css/framework.css}" /> <!-- *** PROBLEM IS HERE *** -->
</head>
<body>
...
</body>
</html>
Here's an application Thymeleaf template (app/start.html)
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8" />
<title th:text="${title}"></title>
<link rel="stylesheet" type="text/css" th:href="#{/resources/css/app.css}" /> <!-- *** This works correctly. *** -->
</head>
<body>
...
</body>
</html>
Here's a sample controller from a web application. Note: this a separate project that depends on the framework library.
#Controller
public class ExampleController
{
#GetMapping(path = "/start")
public String start(Model model, HttpServletRequest request)
{
...
return "app/start"; // Uses an application template
}
#GetMapping(path = "/example")
public String example(Model model)
{
...
return "fwk/example"; // Uses a framework template
}
}
The web application runs under Tomcat and the framework library JAR file is available to it. When I test the controller URLs, both are loaded correctly. That is, in both cases, the template is found, loaded and displayed.
However, as I noted above, the framework template (triggered by the /example URL) is un-styled as its framework CSS file is not found and passed on to the browser. How do I achieve this?
(Is my framework structure okay? Is my ViewResolver configured correctly? Is my resource handling configured correctly? What href path should I use in the framework template to refer to a stylesheet in the same JAR?)
In example.html try replacing:
<link rel="stylesheet" type="text/css" th:href="#{/resources/static/css/framework.css}" />
By:
<link rel="stylesheet" type="text/css" th:href="#{/css/framework.css}"/>

Spring Boot and custom 404 error page

In my Spring Boot application, I'm trying to configure custom error pages, for example for 404, I have added a following Bean to my application configuration:
#Bean
public EmbeddedServletContainerCustomizer containerCustomizer() {
return new EmbeddedServletContainerCustomizer() {
#Override
public void customize(ConfigurableEmbeddedServletContainer container) {
container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/404.html"));
}
};
}
Also, I have created a following simple Thymeleaf template:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<title>404 Not Found</title>
<meta charset="utf-8" />
</head>
<body>
<h3>404 Not Found</h3>
<h1 th:text="${errorCode}">404</h1>
<p th:utext="${errorMessage}">Error java.lang.NullPointerException</p>
Back to Home Page
</body>
</html>
and added it into /resources/templates/ folder. Right now on the 404 error I can see only white screen.
What am I doing wrong and how to correctly setup my 404 page? Also, is it possible to use templates and not only static pages for custom error pages?
In Spring Boot 1.4.x you can add a custom error page:
If you want to display a custom HTML error page for a given status code, you add a file to an /error folder. Error pages can either be static HTML (i.e. added under any of the static resource folders) or built using templates. The name of the file should be the exact status code or a series mask.
For example, to map 404 to a static HTML file, your folder structure would look like this:
src/
+- main/
+- java/
| + <source code>
+- resources/
+- public/
+- error/
| +- 404.html
+- <other public assets>
You're using Thymeleaf, And Thymeleaf can handle error without a controller.
For a generic error page this Thymeleaf page need to be named as error.html
and should be placed under src/main/resources > templates > error.html
For specific error pages, you need to create files named as the http error code in a folder named error, like: src/main/resources/templates/error/404.html.
new ErrorPage(HttpStatus.NOT_FOUND, "/404.html")
That /404.html represents the URL Path to Redirect, not the template name. Since, you insist to use a template, you should create a controller that handles the /404.html and renders your 404.html resides in src/main/resources/templates:
#Controller
public class NotFoundController {
#RequestMapping("/404.html")
public String render404(Model model) {
// Add model attributes
return "404";
}
}
You could also replace these just view render-er controllers with a View Controller:
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/404.html").setViewName("404");
}
}
Also, is it possible to use templates and not only static pages for
custom error pages ?
Yes, it's possible. But Not Found pages are usually static and using a template instead of Plain Old HTMLs wouldn't make that much of a sense.
There is no need for the EmbeddedServletContainerCustomizer bean. Simply putting the corresponding error page (such as 404.html in case of 404) in the public directory should be enough (as pointed by #brunoid).
Also note that you can also put a generic error.html page that'll get displayed whenever your application encounters an error or exception.
A simple example (in Freemarker) -
<html lang="en">
<head>
</head>
<body>
<div class="container">
<div class="jumbotron alert-danger">
<h1>Oops. Something went wrong</h1>
<h2>${status} ${error}</h2>
</div>
</div>
</body>
</html>
This'll display proper error status and corresponding error message. And since you are using Spring Boot, you can always override the status and error messages that get displayed on your error page.
If you are using Thymeleaf like suggested in the question, you could use a template similar to the one from the previous reply, but appropriate for Thymeleaf rather than Freemarker. I have also added bootstrap for the styling:
<!DOCTYPE html>
<html lang="en"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Error Page</title>
<link href="/webjars/bootstrap/3.3.7-1/css/bootstrap.min.css" rel="stylesheet" media="screen"/>
<script src="/webjars/jquery/3.2.1/jquery.min.js"></script>
<script src="/webjars/bootstrap/3.3.7-1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<div class="jumbotron alert-danger">
<h1>Oops... something went wrong.</h1>
<h2 th:text="${status + ' ' + error}"></h2>
</div>
</div>
</body>
</html>
You should place this code in a file called error.html and place it in your thymeleaf templates directory. There is no need to add an additional controller for it to work.
Check if you have thymeleaf present in the classpath, or add below code and reimport the project.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
We have to add new
#Controller
public class MyErrorController implements ErrorController {
#RequestMapping("/error")
public String handleError(HttpServletRequest request) {
Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
if (status != null) {
Integer statusCode = Integer.valueOf(status.toString());
if(statusCode == HttpStatus.NOT_FOUND.value()) {
return "error404";
}
else if(statusCode == HttpStatus.INTERNAL_SERVER_ERROR.value()) {
return "error500";
}
}
return "error";
}
#Override
public String getErrorPath() {
return "/error";
}
}
enter image description hereIt's very easy to do in Spring Boot Application.
Spring Boot all most done all thing for us.
1)In Path src/main/resources/templates
make folder which has name 'error'
2)Next create html file in this folder,
save it as '404.html'.
You done evey thing here.
Spring Boot Automatically show this page if it got 404 page not found error.
Note: Before going to this, make sure that you added Thymeleaf repository in your pom. xml
Thymeleaf can handle error without a controller.
create error.html to resources folder.

JSP cannot find css files while using ResourceHandlerRegistry.addResourceHandler (Java based webConfig)

This is where i put my css file:
This is how i register this resource:
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
This is how i references this css from the JSP:
<link type="text/css" href="/css/bootstrap.css" rel="stylesheet"/>
I can see the JSP page with content but without styling.
I think the error is while referencing but i cant find it. I have tried also these, but does not work:
<link type="text/css" href="../css/bootstrap.css" rel="stylesheet"/>
<link type="text/css" href="/resources/css/bootstrap.css" rel="stylesheet"/>
<link type="text/css" href="<%=request.getContextPath() %>/css/bootstrap.css" rel="stylesheet"/>
<link type="text/css" href="<%=request.getContextPath() %>/resources/css/bootstrap.css" rel="stylesheet"/>
Any idea?
EDIT: Now i have moved the css folder to WebContent. It seems like this:
It still does not work. What should i register for the ResourceHandler?
registry.addResourceHandler("/WEB-INF/**").addResourceLocations("/WEB-INF/"); ?
How should i reference the css from the JSP?
The resource handler doesn't look for resources on the class path, by default. It looks for them in the webapp.
Create a folder called resources and put it in /src/main/webapp. Then put your css, js, etc. folders in there.
The files under src cannot be accessed on default condition , you should put these assets into WebContent directory.
Resources usually means config proppertis like properties and xml, they will be used by the
java code, assets usually mean that can be accessed by the browser directly,Notice that WEB-INF is protected,you need to put your css directory under WebContent, except for WEB-INF
for exampel,you can put your css directory under /WebContent/assets/
And add these code at the head of your jsp pages
<%
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ request.getContextPath();
%>
<link type="text/css" href="<%=basePath%>/assets/css/bootstrap.css" rel="stylesheet"/>
It's not good to use relative path!!

ResourceBundleMessageSource resolving error

I have a JSP-Tagfile which renders the html-header and defines my Javascript/Stylesheet resources.
<%# tag language="java" %>
<%# taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<html>
<head>
<link rel="stylesheet" type="text/css" href="<spring:theme code="main.css"/>"/>
<script type="text/javascript" src="<spring:theme code="default.js"/>"></script>
...
</html>
Now i wan't to load a i18n messages for the javascript stuff.
var button_ok='<spring:message code="js.button.ok" javaScriptEscape="true"/>';
When i use this inside the tag-file it works as supposed and resolves the messages, even if there is only a default messages.properties (fallback).
But if i load the messages with an external javascript file lang.js.jsp it only tries to resolve the message code against the properties for the current language and the fallback to the default one is not working.
If the message should be resolved inside the tag, the ApplicationContext defined within the DispatcherServlet is used. Otherwise the ApplicationContext from the ContextLoaderListener is used (root application context).
To solve the problem i moved the ResourceBundleMessageSource into the configuration which is loaded by the ContextLoaderListener.

Categories