I am doing some basic templating in my JSP-based webapp. For example, I want to have a standard header and footer (basic HTML) that I pull into each of my JSPs.
My content JSP is at /WEB-INF/jsp/home.jsp, and I have template JSPs at /WEB-INF/jsp/template/, such as /WEB-INF/jsp/template/Body-Footer.jsp.
So now, within home.jsp, I want to pull in my template files. First, I try the jsp:include action:
<jsp:include page="template/Body-Footer.jsp"></jsp:include>
It generates the error javax.servlet.ServletException: File "/template/Body-Footer.jsp" not found
Strange to me, considering that Eclipse says that the path is valid.
Okay, so then I switch to the include directive:
<%# include file="template/Body-Footer.jsp" %>
This works just fine, pulls in my footer HTML.
But why does the jsp:include not work? After some experimentation, I find that putting in the absolute path does get it to work:
<jsp:include page="/WEB-INF/jsp/template/Body-Footer.jsp"></jsp:include>
Now it works fine, no errors.
So here's my question: why? Why do I (apparently) need to use an absolute path with the jsp:include action, but not with the include directive?
/WEB-INF/jsp/template/Body-Footer.jsp is not an absolute path. Its also a relative path. The problem is that template/Body-Footer.jsp is an incomplete relative path, whereas the other is complete. That is, the paths are relative to your app path. Since /WEB-INF/ is under your app path, you have to include it. Absolute path means like C:/program files/tomcat/webapps/yourapp/WEB-INF/jsp/template/Body-Footer.jsp
Answer to WHY - The jsp:include is a runtime directive unlike the <%# include ... %> directive which happens to be a compile time directive (translation time, actually).
See more on: JSP Performance using jsp:include
Bottom line - directives are run against different folders as a base.
Btw. JSP pages should be outside of WEB-INF folder, if you want to follow official recommendation:
The Java EE 6 Tutorial - Web Module Structure
I read JSP 2.0 spec and here:
Relative URL Specifications
* A context-relative path is a path that starts with a slash (/).
It is to be interpreted as relative to the application to which
the JSP page or tag file belongs. That is, its ServletContext
object provides the base context URL.
* A page relative path is a path that does not start with a
slash (/). It is to be in- terpreted as relative to the current
JSP page, or the current JSP file or tag file, depending on where
the path is being used.
For now javax.servlet.ServletContext.getRealPath("/WEB-INF/test/test.jsp") is null for security reason.
Assume that context-relative path is path from your WAR root.
Related
My angular application is bundled and deployed together with a java application. Angular AOT build is placed in the folder WebContent/app.
While taking the AOT build,
If I specify --base-href /app, I'm getting 404 after loading the index.html. In that case, I have to add --deploy-url /app/ during my build, for the application to be working properly.
But If I specify --base-href /app/ then scripts, styles, and other resources are served correctly. And there's no need to specify --deploy-url
What I could observe is that If I don't append "/" to base-href, the server request made is using the context-root - http://localhost:9080/application-name/styles.***.css and when I append the "/", server context-root is appended with app - http://localhost:9080/application-name/app/styles.***.css
Why is adding "/" at the end of base-href make all this difference?
Could someone explain this behavior as I'm not able to find anything on docs?
Thanks in Advance.
After some digging, I found the answer. It is not related to Angular at all.
Tha <base> tag is part of HTML Specification: Link
As MDN Doc says,
The HTML < base> element specifies the base URL to use for all relative URLs in a document. There can be only one < base> element in a document.
It is used to specify the base of relative URLs.
So coming into my problem
When <base href="/app"> is used, the browser treats the href as a file rather than a directory. So the base URL will not be prepended to relative URLs.
When <base href="/app/"> is used, the browser treats it as a directory and all relative URLs will be prepended by base URL.
More can be found out here and here
I cloned a Maven Git project and imported it into Eclipse Using File>Import>Maven>Existing Maven Projects. The project compiles and runs, but when I attempt to display a web page, the page is blank and when I use a web inspector I see Head and Body Html tags with no content.
The web pages are in src>main>webapp>WEB-INF>jsp>home.html or login.jsp which are among the files in use. In web.xml I have this entry:
<welcome-file-list>
<welcome-file>home.html</welcome-file>
</welcome-file-list>
Any ideas on what to look for would be appreciated. Thanks
If some files are missing check your .gitignore file and it's restrictions.
Otherwise check view resolver prefix and suffix. If your suffix is .jsp and you have home.html it would not be found beacuse resolver tries to get home.jsp which doesn't exists.
If your prefix is other then WEB-INF/jsp then it's trying to find it in some other directory.
At last check what your controller GET method is returning. Now there are combinations of possible mistakes e.g. if it's returning home.html then it tries to find home.html.jsp which doesn't exists - it needs to return only relative path from prefix and only the name of view without suffix.
I deployed application in tomcat under webapps/testing1 folder.
http://localhost:8080/testing1/index.html
This html page has anchor tag with href as "/login"
When I click on anchor, it takes to localhost:8080/login instead of localhost:8080/testing1/login
I did not do any change in tomcat conf xmls. How can I make all paths starts with slash would goto application context?
Suggestions would be appreciated.
By declaring a link href="/login" you make that an absolute link on your host. If you want login inside your app you'd have to prepend the context path (request.getContextPath ()) or use relative links ( href="login" )
If you deployed context successfully in Tomcat and it is Start up successfully. Then the Application access directly the web.xml from the WEB-INF folder.
It access the servlet using the <url-pattern> and <servlet-class> to identify the servlet.
If you are worrying about accessing HTML files from the servlet you can access them directly from the context path.
i.e
if file present at CONTEXT/html/file1.html you can access it as html/file1.html
if file present at CONTEXT/file2.html you can access it as file2.html
You have to specify the . prefix to the href value.
<a href="./login"> so that the URL will be localhost:8080/testing1/login
I want to create a custom JSP tag as follows.
<ng:template src="../js/Rule/templates/rule-list.jsp" />
Which will actually include the file "../js/Rule/templates/rule-list.jsp" inside a scripts tag and generate HTML as follows.
<script type="text/ng-template" id="../js/Rule/templates/rule-list.jsp">
Content of ../js/Rule/templates/rule-list.jsp file
</script>
So far I have creates following tagfile.
<%# attribute name="src" required="true" rtexprvalue="true" %>
<script type="text/ng-template" id="${src}">
<%# include file="${src}" %>
</script>
Which is giving this error
File "${src}" not found
Means its trying to include the ${src} instated of its value. Can any one suggest how to include file in tag file from specified attribute value?
Note: I am using angularjs. I want to load angularjs templates without ajax call. Because my browser is not able to load ng-template with AJAX call for cross domain call problem.
Got it. I need to use dynamic include as
<jsp:include page="${src}" />
This is working fine.
WEB-INF directory is a special directory that is not part of the public directory tree of your web (Servlet) application.
The Servlet Specification states (page 70 or so):
A special directory exists within the application hierarchy named
“WEB-INF”. This directory contains all things related to the
application that aren’t in the document root of the application. The
WEB-INF node is not part of the public document tree of the
application. No file contained in the WEB-INF directory may be served
directly to a client by the container. However, the contents of the
WEB-INF directory are visible to servlet code using the getResource and
getResourceAsStream method calls on the ServletContext, and may be
exposed using the RequestDispatcher calls.
AngularJS cannot see any folder inside your web application WEB-INF folder since it has no "connection" to it.
You will have to add those template files in a public folder, view-able by your Angular template files.
I'm making a java web app, and I want it to display an image. However, it doesn´t find my image.
I've made a folder in /src/main/resources/images
Also, in the .jsp file, I´ve tried with the following sentences.
<img src="/src/main/resources/images/Head.png"> </img>
<img src="< c:url value='/src/main/resources/images/Head.png'/>"> </img>
Is there anything bad I'm doing?
Thanks
Edit:
The path of mi .jsp file is /src/main/webapp/WEB-INF/jsp/welcome.jsp
You can find the web app code in https://github.com/Santi-7/hello
Your app is a Spring Boot app. I think that you can also try to use the facilities provided by Spring Boot for serving static content. Anyway, you are doing it right now because you are using webjars for css and js libs!!! Be consistent with the tech that you are using.
The structure of a .war file is as follows:
/
/WEB-INF
/lib
/classes
/META-INF
Now, your application has the following structure (I assume, given the folder structure, you are using Maven)
/
/src
/main
/java
/resources
/webapp
Now, the Maven war plugin will copy everything in the classpath to /WEB-INF/classes during compilation - this is /src/main/java and /src/main/resources by default.
The crux of the matter is that nothing under /WEB-INF or /META-INF can be accessed by requests - this is for security as otherwise someone could simply download /WEB-INF/web.xml for example.
So, in order to add a resource that is accessible by a browser, you need to place it into /src/main/webapp - this will become the root of the application.
So if you place Head.png into /src/main/webapp/images then in the JSP you would use:
<c:url value='/images/Head.png'/>
In short, you need to read up on how the directory structure of a .war works and how that relates to your code.
The path to the image must be relative to the path to the .jsp file.
Because the path to your image is: /src/main/resources/images/Head.png, and the path to your jsp file is: /src/main/webapp/WEB-INF/jsp/welcome.jsp, in your image tag you need to write:
<img src="../../../resources/images/Head.png" />
The ../../../ is for getting out from the jsp folder to the main folder, and the resources/images/Head.png is the path from the main folder to the image.
Thanks everybody, i could resolve my problem.
Changes I made:
So, in order to add a resource that is accessible by a browser, you need to place it into /src/main/webapp - this will become the root of the application.
Now, my images are in /src/main/webapp/images.
The path to the image must be relative to the path to the .jsp file.
Now, the sentence of my .jsp file is
<img src="images/Head.png" />
Edit [1]:
¡ I made a mistake. The path to the image is relative to the /webapp classpath !