how to get the base url from jsp request object? - java

How to get the base url from the jsp request object?
http://localhost:8080/SOMETHING/index.jsp, but I want the part till index.jsp, how is it possible in jsp?

So, you want the base URL? You can get it in a servlet as follows:
String url = request.getRequestURL().toString();
String baseURL = url.substring(0, url.length() - request.getRequestURI().length()) + request.getContextPath() + "/";
// ...
Or in a JSP, as <base>, with little help of JSTL:
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%#taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<c:set var="req" value="${pageContext.request}" />
<c:set var="url">${req.requestURL}</c:set>
<c:set var="uri" value="${req.requestURI}" />
...
<head>
<base href="${fn:substring(url, 0, fn:length(url) - fn:length(uri))}${req.contextPath}/" />
</head>
Note that this does not include the port number when it's already the default port number, such as 80. The java.net.URL doesn't take this into account.
See also:
Browser can't access/find relative resources like CSS, images and links when calling a Servlet which forwards to a JSP

JSP variant of Bozho's answer:
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="req" value="${pageContext.request}" />
<c:set var="baseURL" value="${req.scheme}://${req.serverName}:${req.serverPort}${req.contextPath}" />

new URL(request.getScheme(),
request.getServerName(),
request.getServerPort(),
request.getContextPath());

There is one major flaw in #BalusC accepted answer though. Substring should start from 0 and not 1. Instead of
<base href="${fn:replace(req.requestURL, fn:substring(uri, 1, fn:length(uri)), req.contextPath)}" />
it should be
<base href="${fn:replace(req.requestURL, fn:substring(uri, 0, fn:length(uri)), req.contextPath)}" />
With 1 you get double forward slash: http://localhost:8080//appcontext/
With 0 you get, http://localhost:21080/appcontext/
In my application, request.getSession(false) always returned null when it was ending in double slash!!!

Instead of doing all of that, just do this:
request.getServerName().toString()

just use isSecure()
{<%=request.isSecure()?"https":"http:"%>}

Related

How can be a JSP ".tag" file documented?

There is a JSP Tag file like this:
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# attribute name="attr" required="true" type="java.lang.String" rtexprvalue="true" description="FOOO" %>
<%# attribute name="var" required="true" type="java.lang.String" rtexprvalue="false" description="BAAR" %>
<%# variable name-from-attribute="var" variable-class="java.lang.String" alias="attrValue" scope="AT_BEGIN" %>
<c:set var="attrValue" value="${requestScope[attr]}" />
It seems to be possible to document the attributes. How to add documentation to the tag itself?
The proper place to describe a tag and its properties (including attributes) is the Tag Library Descriptor. The description attribute of the attribute directive is IMHO a left-over "from the dark past" and does not have any real use nowadays.

get current url of context

I want to get the current URL of my website.
Not the context, not the ports, not the scheme or the protocol. Only the relative url.
For example:
https://www.myurl.com/context/relative/url/site.mvc
I want to have:
/relative/url/site.mvc
${pageContext.request.contextPath} gives me: /context/
${pageContext.request.requestURL} gives me https://www.myurl.com/context/WEB-INF/tiles/relative/url/site/center.jsp
Thats where the site is located in my directory.
But I want the relative path of the website... without Javascript!
So, you want the base URL? You can get it in a servlet as follows:
String url = request.getRequestURL().toString();
String baseURL = url.substring(0, url.length() - request.getRequestURI().length()) + request.getContextPath() + "/";
// ...
Or in a JSP, as , with little help of JSTL:
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%#taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<c:set var="req" value="${pageContext.request}" />
<c:set var="url">${req.requestURL}</c:set>
<c:set var="uri" value="${req.requestURI}" />
...
<head>
<base href="${fn:substring(url, 0, fn:length(url) - fn:length(uri))}${req.contextPath}/" />
</head>
Note that this does not include the port number when it's already the default port number, such as 80. The java.net.URL doesn't take this into account.
See also:
Browser can't access/find relative resources like CSS, images and links when calling a Servlet which forwards to a JSP
jsp file:
request.getAttribute("javax.servlet.forward.request_uri")
Thank you #jmail.
Your statement brought me on the right track. But I did not want the base url, but the solution would be this:
<c:set var="currentUrl" value="${pageContext.request.request.getAttribute('javax.servlet.forward.request_uri')}"/>
<c:set var="contextPath" value="${pageContext.request.contextPath}"/>
<c:forEach items="${paramValues}" var="paramItem">
<c:set var="urlParams" value="${urlParams}&${paramItem.key}=${paramItem.value[0]}"/>
</c:forEach>
<c:set var="urlParams" value="${fn:substring(urlParams, 1, fn:length(urlParams))}" />
<c:set var="relativeUrl" value="${fn:substring(currentUrl, fn:length(contextPath), fn:length(currentUrl))}?${urlParams}" />
You forgot the parameters, and your version extracted the base, instead of the relative path!

Composing URL in JSP

Lets say my current URL is:
/app.jsp?filter=10&sort=name.
I have a pagination component in JSP which should contain links like:
/app.jsp?filter=10&sort=name&page=xxx.
How do I create valid URLs in JSP by adding new parameters to current URL? I dont want use Java code in JSP, nor end up with URLs like:
/app.jsp?filter=10&sort=name&?&page=xxx, or /app.jsp?&page=xxx, etc.
Ok, I found answer. First problem is that I have to preserve all current parameters in URL and change only page parameter. To do this I have to iterate over all current parameters and add those I don't want to change to URL. Then I added parameters I want to either change or add. So I ended up with solution like this:
<c:url var="nextUrl" value="">
<c:forEach items="${param}" var="entry">
<c:if test="${entry.key != 'page'}">
<c:param name="${entry.key}" value="${entry.value}" />
</c:if>
</c:forEach>
<c:param name="page" value="${some calculation}" />
</c:url>
This will create nice and clean URL independent of page parameter in request. Bonus to this approach is that URL can be just anything.
<c:url var="myURL" value="/app.jsp">
<c:param name="filter" value="10"/>
<c:param name="sort" value="name"/>
</c:url>
To show the url you can do something like this
Your URL Text
To construct a new URL based on the current URL, you first need to get the current URL from the request object. To access the request object in a JSP use pageContext implicit object defined by the JSP expression language:
${pageContext.request.requestURL}
Here is the simple example of constructing URL in a JSP page:
test.jsp
<%# page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<title>Test Page</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<h1>Testing URL construction</h1>
<c:choose>
<c:when test="${pageContext.request.queryString != null}">
Go to page xxx
</c:when>
<c:otherwise>
Go to page xxx
</c:otherwise>
</c:choose>
</body>
</html>
This solution allows you to construct URLs depending on whether the current URL already contains some query string or not. So you respectively append either
?${pageContext.request.queryString}&page=xxx
or just
?page=xxx
to the current URL.
JSTL and the Expression Language were used to implement checking for a query string. And we used getRequestURL() method to obtain the current URL.

JSTL - Output not coming as expected

Below is the code I have in index.jsp using jstl 1.2.
<%# taglib prefix = "c" uri="http://java.sun.com/jstl/core"%>
<% String[] setName = {"Hello", "you", "are", "using", "jstl", "in", "jsp"};
request.setAttribute("getName", setName);
%>
<html>
<body>
<table>
<tr><td>Print</td></tr>
<c:forEach var="itemName" items="#{getName}" >
<tr>
<td>${itemName}</td>
</tr>
</c:forEach>
</table>
</body>
</html>
The output I was expecting is as below
Print
Hello
you
are
using
jstl
in
jsp
However below is what I am getting
Print
#{name}
Please let me know where I am missing
Below is the only jar file I have in WEB-INF/lib folder
jstl-1.2.jar
Thanks in advance
Fahim
Note: Adding Java and JSP tag as person who have knowledge of Java and JSP might be knowing JSTL too...
Here,
<%# taglib prefix = "c" uri="http://java.sun.com/jstl/core"%>
You're specifying the wrong JSTL taglib URL. This one is for JSTL 1.0. After JSTL 1.1 it requires a /jsp in the path. See also the JSTL 1.1 tag library documentation.
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
As to the of the code (and to reply on all those duplicate answers complaining to use ${} instead), the #{} syntax will only work inside JSP when you're targeting a Servlet 2.5 / 2.1 compatible container with a web.xml conforming Servlet 2.5 spec. Tomcat 6.0 is an example of such a container. The #{} will indeed not work in JSP tags on older containers such as Tomcat 5.5 or older.
For clarity and to avoid confusion among starters, better use ${} all the time in JSP tags. Also better use self-documenting variable names.
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
String[] names = {"Hello", "you", "are", "using", "jstl", "in", "jsp"};
request.setAttribute("names", names);
%>
<!DOCTYPE html>
<html lang="en">
<head>
<title>JSTL demo</title>
</head>
<body>
<table>
<tr><td>Print</td></tr>
<c:forEach items="${names}" var="name">
<tr><td>${name}</td></tr>
</c:forEach>
</table>
</body>
</html>
See also:
Our JSTL wiki page
Difference between JSP EL, JSF EL and Unified EL
In JSTL 1.2, you don't want to use #{name} in pure JSP, that's only a JSF artifact. Instead, simply use ${name}.
You need to refer items using expression language like ${name}
U r using # instead of $ before name
Let me know if this resolves.
#{name} is not a valid Java variable reference - looks like you are confusing it with JQuery selector.
Anyways try just using items="${name}"
#{name} is should be like ${name}
oh! might be the jars related to JSTL. check thins link for those jars to include in your project
Below is the final code I am using and it is running...
Posting so that someone can use it... Might help me tomorrow ;)
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<% String[] setName = {"Hello", "you", "are", "using", "jstl", "in", "jsp"};
request.setAttribute("getName", setName);
%>
<html>
<body>
<table>
<tr><td>Print</td></tr>
<c:forEach var="itemName" items="#{getName}">
<tr>
<td>${itemName}</td>
</tr>
</c:forEach>
</table>
</body>
</html>
Learning : I was using <%# taglib prefix="c" uri="http://java.sun.com/jstl/core" %> instead of <%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

Passing an ArrayList from a Servlet to JSP

my model returns an arraylist of strings to servlet in the form
ArrayList<String> currentCustomer = model.getAllCustomers();
i want to pass this arraylist from the servlet to the jsp page. how do i do this? below is what i tried
req.setAttribute("currentCustomer", currentCustomer);
and in the jsp page, i want to use JSTL to loop over each value and display it. how do i do that? its frustrating me to no end. ive scoured the web but to no avail. any help is greatly appreciated.
here is the jsp code
<%# taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<body>
<div>
<c:forEach var="customer" items="currentCustomer">
${customer}
</c:forEach>
</div>
</body>
Let's make it work :)
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
...
<c:forEach var="customer" items="${currentCustomer}">
<c:out value="${customer.name}" />
<c:out value="${customer.age}" />
</c:forEach>
P.S. jsp:useBean is another way to go...
P.P.S. I also made a correction in the taglib import. That's one of these hard-visible mistakes when you can look on two different entries and think they are the same :)
its allrite guys, i solved the problem.. thanks for your help..
apparently the code i was using was outdated (thanks internet!) i was writing this on the header:
<%# taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
while it should have been
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
It will be smt like
<c:forEach var="currentCustomer" items="${customers}">
${currentCustomer.name}
${currentCustomer.age}
</c:forEach>

Categories