I am learning JSP. I am not able to find out how sessions got created in JSP.
what I know till now is session is implicit object creates under _jspService method. So I manually created session. In below JSP code I created session same as it automatically creates in index_jsp but i am getting value as null. So any body can explain me why I am getting null?
<%# page import ="java.util.*" session="false" %>
<%
javax.servlet.http.HttpSession session = null;
session = pageContext.getSession();
%>
<html>
<body>
<%=session %>
</body>
As you said:
session is implicit object created under _jspService method
The JSP file is compiled by the Jasper Engine to a java class. Despite of the code you have writen in the JSP, in the created Java class there are some preparation of these implicit objects.
Therefore you don't need to do it again.
You can just use them. You can write in your JSP the code:
From EL:<br>
sessionScope.name: ${sessionScope.name}<br>
<br>
From Scriptlet. <br>
<%=session.getAttribute("name")%>
And you get the same output twice: the value of the session attribute "name".
In example of a JSP with content:
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Title</title>
</head>
<body>
From EL:<br>
sessionScope.name: ${sessionScope.name}<br>
<br>
From Scriptlet. <br>
<%=session.getAttribute("name")%>
</body>
</html>
Will result in a java class file:
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class testcompile_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();
private static java.util.List<String> _jspx_dependants;
private org.glassfish.jsp.api.ResourceInjector _jspx_resourceInjector;
public java.util.List<String> getDependants() {
return _jspx_dependants;
}
public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws java.io.IOException, ServletException {
PageContext pageContext = null;
HttpSession session = null;
ServletContext application = null;
ServletConfig config = null;
JspWriter out = null;
Object page = this;
JspWriter _jspx_out = null;
PageContext _jspx_page_context = null;
try {
response.setContentType("text/html; charset=UTF-8");
response.setHeader("X-Powered-By", "JSP/2.3");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
_jspx_resourceInjector = (org.glassfish.jsp.api.ResourceInjector) application.getAttribute("com.sun.appserv.jsp.resource.injector");
out.write("\r\n");
out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n");
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\r\n");
out.write("<title>Title</title>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");
out.write("From EL:<br>\r\n");
out.write("sessionScope.name: ");
out.write((java.lang.String) org.apache.jasper.runtime.PageContextImpl.evaluateExpression("${sessionScope.name}", java.lang.String.class, (PageContext)_jspx_page_context, null));
out.write("<br>\r\n");
out.write("<br>\r\n");
out.write("From Scriptlet. <br>\r\n");
out.print(session.getAttribute("name"));
out.write("\r\n");
out.write("</body>\r\n");
out.write("</html>");
} catch (Throwable t) {
if (!(t instanceof SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
out.clearBuffer();
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
As you can see in the _jspService method there are lines:
HttpSession session = null;
...
session = pageContext.getSession();
Basically this is the implicit session object. Your code follow after that and can use it.
EDIT:
With <%# pagesession="false" %> you say "i don't need the session". So the session is not bond in the pageContext. Therefore you if you call pageContext.getSession() you receive null;
If you need it you have to use:
request.getSession();
Can explain me why I am getting null for session ?
The session in the JSP file will be disabled if you set the session attribute to false i.e., session="false", you can look here for more details.
I am not able to find out how sessions got created in JSP.
httpsession object will be created (& maintained) by the servlet container when you invoke request.getSession(true); from JSP (because request is also an implicit object in JSP).
public HttpSession getSession(boolean create) : Returns the current
HttpSession associated with this request or, if there is no current
session and create is true, returns a new session. If create is false
and the request has no valid HttpSession, this method returns null.
You can refer the API here
So, to create the session from your code you change it as:
<%
javax.servlet.http.HttpSession session = request.getSession(true);
// you can session object from now add attributes,
// get attributes, remove attributes, etc..
%>
Also, once the session is created (as shown above using request.getSession(true)), you need to use request.getSession() to retrive the same session object.
In other words, in your whole application,
(1) Create the session ONLY ONCE during the user login time in LoginServlet or LoginController class using request.getSession(true)
(2) And then use request.getSession() in all other servlet/controller methods.
As a side note, I strongly suggest you to use Controller (like using Spring) or Servlet classes to write the Java code because JSP is meant only for the presentation layer (to display the html content).
Related
When I visit my page .../index.jsp while having no HttpSessions, index.jsp still creates the JSESSIONID-cookie. Even worse, in the servlet responsible for logging people out, session.invalidate() does not seem to fix the issue.
index.jsp looks like this:
<%#page import="javax.servlet.http.Cookie"%>
<%#page contentType="text/html" pageEncoding="utf-8"%>
<%#page session="true"%>
<%!
void removeJSessionIdCookie(HttpServletResponse response) {
Cookie cookie = new Cookie("JESSIONID", "");
cookie.setValue(null);
cookie.setMaxAge(0);
cookie.setPath("/");
response.addCookie(cookie);
}
%>
<%
if (session != null) {
out.print("Session not null.");
if (session.getAttribute(Config.CURRENT_USER_ATTRIBUTE) != null) {
out.print("have user");
request.getRequestDispatcher("app.jsp").forward(request, response);
return;
} else {
out.println("no user here");
session.invalidate();
removeJSessionIdCookie(response);
}
}
%>
<html>...</html>
If you have session="true" in your <%#page%> directive, then the JSP framework code always creates a new session if the calling client does not bring a session cookie, i.e. has no session yet.
You need to put session="false" in to the page directive; this makes the Framework stop creating sessions for you.
I am trying to pass an attribute from a java servlet to jsp and write this attribute on jsp file. However it does not redirect to jsp file url but it writes the content of the jsp file. Here is my related codes:
Control.java:
#WebServlet("/Control")
public class Control extends HttpServlet{
#Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Key key = MacProvider.generateKey();
long time = System.currentTimeMillis();
try{
String jwt = Jwts.builder()
.signWith(SignatureAlgorithm.HS256, key)
.setSubject("username")
.setIssuedAt(new Date(time))
.setExpiration(new Date(time+6000000))
.claim("password","password")
.compact();
req.setAttribute("jwt", jwt);
req.getRequestDispatcher("/Home.jsp").forward(req,resp);
}catch (Exception e){
e.printStackTrace();
}
}
}
Home.jsp:
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Welcome</title>
</head>
<body>
${jwt}
</body>
</html>
Here, browser stays on http://localhost:8080/Control but it writes the content of Home.jsp file which is just a java web token result string.
2) My second question is when I tryed to store this jwt result string in browser local storage and then write it in jsp file in order to check if it stored in browser or not. But it does not prints anything. To do this, I just changed the Home.jsp file as follow:
(I took both of the code snippets from here)
Home.jsp:
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Welcome</title>
</head>
<body>
<script>
localStorage.setItem("jwt", ${jwt});
console.log(localStorage.getItem("jwt"));
var jjwt = localStorage.getItem("jwt");
document.write(jjwt);
</script>
</body>
</html>
Another try:
<html>
<head>
<script>
function myFunction() {
localStorage.setItem("jwt", ${jwt});
console.log(localStorage.getItem("jwt"));
var jjwt = localStorage.getItem("jwt");
document.getElementById("myText").innerHTML = jjwt;
}
</script>
</head>
<body onload="myFunction()">
<span id="myText"></span>
</body>
</html>
Where am I doing wrong?
1) When you use RequestDispatcher.forward(request,response), your servlet will still have control but your jsp page will be loaded so this is nothing to worry about.
If you want your browser URL to show your JSP page URL, do response.sendRedirect("URL TO LOAD");
2)Since you are using JSP, try accessing the request variables like below and print it
<% String jwt = (String) request.getAttribute("jwt");%>
We need to set it as
localStorage.setItem('jwt', <%=jwt%>);
In my login servlet, the last code of doPost is as follows:
HttpSession session = request.getSession();
session.setAttribute(Config.CURRENT_USER_PARAMETER, user);
request.getRequestDispatcher("app.jsp").forward(request, response);
What comes to app.jsp, it is as follows:
<%#page import="fi.vakuutustiedot.controllers.Config"%>
<%#page import="fi.vakuutustiedot.model.User"%>
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<%
if (session == null) {
request.getRequestDispatcher("index.html").forward(request, response);
return;
}
User user = (User) session.getAttribute(Config.CURRENT_USER_PARAMETER);
if (user == null) {
session.invalidate();
request.getRequestDispatcher("index.html").forward(request, response);
return;
}
%>
<!DOCTYPE html>
...
My problem is the following scenario:
I login through the HTML form that is connected to my login servlet.
The login servlet creates a HttpSession and adds an attribute for the object describing the user in question.
Finally, it forwards to app.jsp.
The problem is that when I am logged and forwarded to app.jsp, I see everything I am supposed to see, but if I type .../app.jsp in the location bar and press Enter it redirects to index.html! However, when I visit app.jsp the second, third, .etc time, everything is fine and no spurious redirect to index.html happens.
Is this solution adequate from the security standpoint?
I resolved the issue by adding in the login servlet the following line:
HttpSession session = request.getSession();
request.setAttribute(Config.CURRENT_USER_PARAMETER, user); // <- The new added line.
session.setAttribute(Config.CURRENT_USER_PARAMETER, user);
request.getRequestDispatcher("app.jsp").forward(request, response);
And in app.jsp I have:
<%#page import="fi.vakuutustiedot.controllers.Config"%>
<%#page import="fi.vakuutustiedot.model.User"%>
<%#page import="fi.vakuutustiedot.model.UserType"%>
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<%! User user = null; %>
<%
if (session == null) {
request.getRequestDispatcher("no_session.html").forward(request, response);
return;
}
user = (User) session.getAttribute(Config.CURRENT_USER_PARAMETER);
if (user == null) {
user = (User) request.getAttribute(Config.CURRENT_USER_PARAMETER);
}
if (user == null) {
request.getRequestDispatcher("test.jsp").forward(request, response);
return;
}
%>
<!DOCTYPE html>
...
Answering my own question
In the login servlet, all I do is:
HttpSession session = request.getSession();
session.setAttribute(Config.CURRENT_USER_PARAMETER, user);
response.sendRedirect("app.jsp");
That way, the user object is available straight from the session and I do not need to put that user to the request object.
It would seem you are trying to get to a page outside of your context.
By your question, I am only guessing your directory is:
/index.html
/app.jsp
When you are running your application, you probably inter a URI such as:
http://[my_server]/[my_app]/index.html
or just:
http://[my_server]/[my_app]/
When you type ../app.jsp, your are trying to get something that is not there. Your server is probably set to send a default page of index.html with no default error page.
I am guessing you are just getting back the index.html page because of the incorrect URI.
I have made an AJAX call to a JSP, which in turn calls a Java method in a separate Java class. All files are in the same folder.
For some reason, I can't get the correct value returned to AJAX. It simply prints the whole JSP content.
JavaScript:
var xhr = new XMLHttpRequest();
xhr.onload = function() {
if(true){
alert('hello!');
var response = xhr.responseText;
alert(response);
document.getElementById('newgame').innerHTML = xhr.responseText;
}
};
xhr.open('GET', 'javaconnect.jsp', true);
xhr.send(null);
JSP:
<%# page import="com.example.Server"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<%
Server tc = new Server();
out.print(tc.highScore());
%>
</body>
</html>
Java class:
package com.example;
public class Server {
public String highScore() {
return "hello!!!";
}
}
The best solution is to use a Servlet to make the control layer in place of jsp that instantiates the Server class, like:
public class HelloWorld extends HttpServlet {
protected void doGet (HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
Server tc = new Server();
String txt = tc.highScore();
response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(txt);
}
}
Do not forget to map the servlet and change the url of the ajax call.
You can test call
I have a JSP file and I need to use it to return the user stored in the session object:
Factory.jsp:
<%#page import="users.User"%>
<%!
public static class Factory{
public Factory(){
}
public static User getUser(){
//session.getAttribute("loggedUser"); doesn't work
return null;
}
}
%>
<%
//some code
%>
Is there a way to access the session object within the getUser() method?
You would not have to use scriptlets if you were using any framework.
Try below code :
<%!
Session session = request.getSession();
%>
Then use session object to get variables from it.
<%
User user = session.getAttribute("loggedUser");
%>