How can I save to the session a variable at the very start of the application?
The below code isn't executed when I fist run the application..
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession(true);
session.setAttribute("flag", true);
//etc...
}
That code wont be executed at server startup, because there is no request and therefore no session at this time. This method belongs to a servlet, which is invoked once some client hits the url mapped to it.
If you need to do something at application startup use a ServletContextListener. If you have to store some variable for "global" use in your webapp use the ServletContext. If you really have to store it to the session use an HttpSessionListener.
Related
I'm new to Java Servlets, and for the application I'm currently working on, (some kind of Proxy without forwading or Redirect classes) I would like to save an object to the context path of the application.
I know there are similar questions, but I can't get it to work or I just don't understand it.
Do I have to specifiy the context path in the web.xml?
Do I Need a context listener?
This is the code snippet but the Objects within the saved Object are null;
how can I save the current state of an Object to the context path?
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
if(this.getServletContext().getAttribute("oldConnector")==null){
Connector connection = new Connector();
connection.sendRequest(request);
this.getServletContext().setAttribute("oldConnector", connection);
}else{
((Connector)this.getServletContext().getAttribute("oldConnector")).sendResponse(response);
this.getServletContext().removeAttribute("oldConnector");
}
The response object of HttpServletResponse is never null, because it is created by the web container when a first request is made to your servlet.
Therefore, the attribute "oldConnector" is not set, so you are getting its value as null.
Suggestion: Set the context attribute "oldConnector" by removing the if(response==null) condition. And retrieve that attribute in another servlet or same then remove it if required to.
Below code may help you for your query in comments.
if(getServletContext().getAttribute("oldConnector") == null){
getServletContext().setAttribute("oldConnector", "old value");//dummy value added, replace it with your connection object.
System.out.println("oldConnector attribute has be set.");
}else{
getServletContext().removeAttribute("oldConnector");
System.out.println("oldConnector attribute has be removed");
}
I have passed the HttpServletRequest to another method in the servlet. Could I keep the servlet thread-safe? Is the below code thread-safe with er() method?
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().append("Your session Id: ").append(er(request));
}
public String er(HttpServletRequest request){
return request.getSession().getId();
}
it is perfectly fine, you are not modifying any state within the Servlet itself, the servlet lifecycle creates one instance of the servlet and calls the init() method, any additional requests come through the same instance. so if you don't have any unprotected instance variables, you should be fine.
Because request.getSession() optionally creates a session, the answer is that you may have a race condition where to "simultaneous" calls from the same client may result in different session objects created for that client and consequently, different IDs returned.
See also here
f got my application layer that works basically with spring+jsf(2.0) with primeFaces(3.5)+hibernate(4.3.5). Now we had to put a new way to access the DAO that goes outside the spring and the jsf, we have created a Rest path. The problem is: when i access my application with the browser and login first everything works correctly, including the Rest access to the DAO. The problem is when i try to access the Rest without the login. I tried to make a filter that intercept anything that goes through /rest/* path where i wrote:
#Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)arg0;
HttpSession session = req.getSession(true);
HttpSession session2 = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
arg2.doFilter(arg0, arg1);
}
But it doesn't work because the first session that i get is not the session that i want (it's outside the JSF context) and the first try to get the session from FacesContext gives me error because i'm outside JSF cycle that begins when i call something with *.jsf... the problem is that i can't call my Rest with a .jsp in the end and i can't get the data i need in DAO without the session. There is someway to bypass this problem?
I found a solution using the #Transactional annotation. Thanks!
I think there should a way to set session variable with defined scope in pure java Servlet without using other library like jsf or springframework so that visibility of session variable can be restricted.
public void doGet(HttpServletRequest request, HttpServletResponse response) {
HttpSession session = request.getSession();
String userId = (String)request.getAttribute("userId");
session.setAttribute("userId", userId);
}
I found ServletContext
ServletContext context = request.getSession().getServletContext();
context.setAttribute("userId", userId);
but this one doesnot seem to provide session scope flexibility.
You've found it. Set a session attribute. The scope of a session attribute is the scope of a session, which is a single user.
The portlet scope just controls whether the attribute is confined to the current portlet or is visible to all portlets. It's still within the user session. If you need to implement that feature, just bind a Map into the session under the name of the portlet, and have each portlet look in its own Map.
If you set a context attribute it will be visible to all users.
General question about java servlets and the best way to handle requests. If I hit my doGet method from a remote server request:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
....
<do work here>
....
kill(request);
}
private void kill(HttpServletRequest request) {
//How do I kill the user session here?
}
After I process the request at my end and generate my output to the requester, I want to basically "kill" their session. Currently, that session lingers and thus eats up memory. Then once the max is reached, all other calls are timed out.
I tried creating a HttpSession object using the request object, but got the same results:
HttpSession session = request.getSession();
session.invalidate();
HttpSession session = request.getSession(false);
if (session != null) {
session.invalidate();
}
is the proper way to go as suggested by the documentation. A new session will be created once the client sends a new request.
You mentioned that your sessions still take up memory. Do you have any other references to those objects on the session?
You also might want to have a look at: Servlet Session behavior and Session.invalidate
you can remove an attribute from a session using
session.removeAttribute("attribute name");
Try with
session = request.getSession(false); // so if no session is active no session is created
if (session != null)
session.setMaxInactiveInterval(1); // so it expires immediatly
If you dont want Session behavior i.e, having state between multiple requests. Why do you want to create/use session at all. Do not create session or do not store anything in the session.
To make sure that your code is not using session, write a request wrapper which will override getSession() methods.
Set a time-out period in web.xml