I am working on a webapp in WinXP, Eclipse Indigo and Google web plugin.
I have a simple form that takes a value from user (e.g email) , passes it to a servlet named SignIn.java that processes it and saves the email value to the session.
The SignIn code is very simple , here is what its doGet mostly does:
String email = req.getParameter("email"); //getting the parameter from html form
...
...
HttpSession session = req.getSession(); //create a new session
session.setAttribute("email", email);
So far so good, I've verified that the values aren't null at this point. Now comes the problem, I want to redirect to another servlet (ShowOnline.java) that needs to do some more processing. When I write
resp.sendRedirect(resp.encodeRedirectURL("/ShowOnlineServlet"));
ShowOnline gets null session values (the same email attribute I saved a second before is now null)
When I write
getServletConfig().getServletContext().getRequestDispatcher("/ShowOnlineServlet");
everything is OK, the email attribute from before isn't null!
What is going on? sendRedirect() just makes your browser send a new request, it shouldn't affect the session scope. I have checked the cookies and they are fine (it is the same session from before for sure since it is the first and only session my webapp creates and furthermore I even bothered and checked the sesison ID's and they're the same on both requests).
Why would there be a difference between sendRedirect() and forward()? The easy solution would be to use forward() but I want to get to the bottom of this before I just let go , I think it is important for me to understand what happened. I'm not sure I like the idea of not knowing what's going on on such basic concepts (my whole webapp is very simple and basic at this point since I'm a beginner).
Any thoughts ideas or suggestions would be warmly welcome !
If your SignIn servlet is only saving a request parameter (email), then you could also replace the servlet with a filter, e.g. SignInFilter.
SignInFilter would contain the same logic as your SignIn servlet (copying the email from the request parameters to the session), but would call the next item in the chain (which will be your ShowOnline servlet) instead of doing any redirect/forward.
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession();
String email = req.getParameter("email");
session.setAttribute("email", email);
chain.doFilter(req, res); // continue to 'ShowOnline'
}
Set up your form to POST to the ShowOnline servlet instead, and configure your new SignInFilter to execute before ShowOnline (servlet mapping omitted below for brevity).
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<filter>
<filter-name>SignInFilter</filter-name>
<filter-class>com.example.SignInFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SignInFilter</filter-name>
<url-pattern>/ShowOnline</url-pattern>
</filter-mapping>
</web-app>
As far as my knowledge, sendRedirect() just redirects the control to another page without transfering the associated request & response object of parent page, but RequestDispatcher(object) will dispatch the ServletRequest and ServletResponse to the page mentioned in path argument { getServletContext().getRequestDispatcher("path")} after that you can either forward the objects to that page or include the objects. So by this container becomes assured that he has to use the previous request and response object from of the parent page instead of creating new one.
Specially if you are using session management the best option is RequestDispatcher.
Hope that answers the question.
To All :- Please correct me if i am wrong.
#rs
Related
This is a duplicate of this question, but that question is over 4 years old and doesn't have an accepted answer. I'll offer bounty from this question if it does not get an answer.
In my J2EE web application, I have a Filter called AlwaysCreateSessionFilter. Here is my doFilter method:
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) {
if (request instanceof HttpServletRequest) {
((HttpServletRequest) request).getSession();
}
chain.doFilter(request, response);
}
And in this war's web.xml, I have:
<session-config>
<session-timeout>30</session-timeout>
<cookie-config>
<http-only>true</http-only>
<secure>true</secure>
</cookie-config>
<tracking-mode>COOKIE</tracking-mode>
</session-config>
The browser always correctly includes a JSESSIONID cookie with the value from the server's most recent response (provided in the response's Set-Cookie header). But the problem is that the server always provides a brand new value for JSESSIONID in the Set-Cookie header, not the same one provided with the request. So the server is creating a new session on each request.
I have set a breakpoint in the doFilter method, and can confirm that request.getSession(false) returns a valid session with the correct id that corresponds to the value of the JSESSIONID cookie being provided with the request. It's just that, when the server responds, it always has that Set-Cookie header set to a brand new JSESSIONID, and I can't figure out what is doing it.
Here is crude diagram to illustrate what is happening:
Any help would be appreciated.
My question is simple - how to implement login-logout in servlet jsp?
Following is the use case...
I have a users table in DB with email,username and password
I have a mapped bean object - User in java having email,username,password properties
Simply I want to login by validating email and password BUT
Once I login and then logout, when I click on back button, it should not retain the session.
It should not give any warning BUT simply should ask for login
If I copy-paste restricted resource's link, it should ask for login
What all solutions I've gone through...
Some say to implement tomcat security using roles and bla bla... BUt I think I should not set username, passwords in some tomcat config file. Bcz the details are in DB table
Some ask to implement no-cache, pragma bla bla... but never work
Back button disable is foolish thing
**
What Help I am expecting from you guys ...?
**
Is there any third-party API available to do this?
How things are implemented in production ready applications ?
Should I use JAAS, or any other security process for exactly above mentioned scenario OR WHAT
Please give me some hint or solution how I should proceed implementing production ready login-logout in servlet-jsp
I've searched on internet but end up with simple Login examples or tomcat security roles etc. No one gives the actual solution. ANd please don't say that this question is NOT RELATED TO this FORUM.
Thanks
This happens because browser caches the web pages that are being loaded,you can prevent it by using filters and telling browser not to cache the web pages like below.
doFilter method of Filter
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
HttpSession session = request.getSession(false);//don't create if session doesn't exist.
if (session==null || session.getAttribute("username") == null) {
RequestDispatcher rd=request.getRequestDispatcher("login");//dispatch it to your desired page i.e login page
rd.forward(request, response);
} else {
chain.doFilter(req, res);
}
}
You should configure this filter inside web.xml or using Annotations for which url-patterns you want to filter.refer documentation for more details.
If you're using Tomcat then a good place to start is Tomcat Standard Realm Implementations.
It's important to remember that normal Java EE security authenticates users and authorises them using roles - even if you only have the one.
Once you have done that you can implement Logout by invoking a servlet which calls HttpServletRequest.logout() and then invalidates the HttpSession:
request.logout();
request.getSession().invalidate();
and then:
response.sendRedirect("some protected page");
which should resolve your back button problem and land back on the login page.
I want to intercept all incoming requests e.g.
http://subdomain.domain.org/path/to/resource
to
https://appengineid.appspot.com/path/to/resource
for any possible /path/to/resource
Is this possible with the app engine web.xml deployment descriptor?
When I search this topic all the documentation or questions/answers relate to transforming/translating the /path/to/resource part of a request rather than the subdomain.domain.tld part?
Thanks
QUESTION EDIT/UPDATE:
Both of the above URLs point to the exact same instance of an app engine application. I don't want to URL pattern match on the /path/to/resource because this would "match" requests to both URLs. I want to URL pattern match on the domain part of the URL, so that any requests to subdomain.domain.org are redirected to appengineid.appspot.com, and then, so that no cycle is encountered any requests to appengineid.appspot.com are ignored by the redirecting filter and are handled by the rest of the web deployment descriptor.
It seems to be that a Filter will solve your problem.
You create a new filter in your web.xml, like this:
<filter>
<filter-name>yourFilterName</filter-name>
<filter-class>com.acme.filter.YourNewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>yourFilterName</filter-name>
<url-pattern>/path/to/resource/*</url-pattern>
</filter-mapping>
Your filter class will be something like this:
public class YourNewFilter extends MyGenericFilter implements Filter {
public void doFilter(final ServletRequest request,
final ServletResponse response,
FilterChain chain)
throws java.io.IOException, javax.servlet.ServletException {
ServletContext context= getServletContext();
req.getRequestURL().toString() // use this method to get the end of the URL
RequestDispatcher rd= context.getRequestDispatcher("https://appengineid.appspot.com/path/to/resource/" + end of the URL
);
rd.forward(request, response);
}
}
It is gonna intercept all requests in one domain and dispatch it to another.
I have Spring app that uses JSP. And I need to redirect one page, but only once. It's due the spring security - once the user comes to this page, I need to call redirection to log him out, but to stay on the same page. Is there any way, how to do this only via java, html or js? Or maybe I've asked wrong - there must be some way, how to do this, but I'm not very into frontend technologies, so I'd be glad, if anybody could post some code to show me, how to make this work.. Thanks :)
So the usecase: user types mywebsite.com/login -> I need to call redirect to log him out in the case he's already logged -> the same site shall appear but now without redirection.
PS: I can't redirect the user to another site - it must be the same site with same source code.
If I understand your use case, I would rather log out a user as a part of the login action (i.e. factor out the logging out process, and call it from both the logout action, as well as from the login action).
If that is not feasible (and I can't of a reason why it wouldn't be), I would focus on "redirect if he's logged in" part rather than "redirect only once" part - the former is very easy to check without almost any modification to your code, assuming you're using some kind of sessions to track the logged-in status.
Disclaimer: I know next to nothing about Sprint, these are all very general comments that should work on any classic webapp.
You can use filter .
#Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException {
HttpServletRequest test1= (HttpServletRequest) arg0;
test1.getRequestURL()); it gives http://localhost:8081/applicationName/menu/index.action
test1.getRequestURI()); it gives applicationName/menu/index.action
String pathname = test1.getServletPath()); it gives //menu/index.action
if(pathname.equals("//menu/index.action")){
arg2.doFilter(arg0, arg1); // call to urs servlet or frameowrk managed controller method
// in resposne
HttpServletResponse httpResp = (HttpServletResponse) arg1;
RequestDispatcher rd = arg0.getRequestDispatcher("another.jsp"); redirect to another page at response time
rd.forward(arg0, arg1);
}
donot forget to put <dispatcher>FORWARD</dispatcher> in filter mapping in web.xml
If you do not want to use filter you can redirect to another jsp from urs controller method.
I am running Tomcat 5.5.4 and have a servlet running with no problems. However, I'd like to set up a mapping to only launch the servlet when a URL containing a particular query string is submitted.
Right now in web.xml I have:
<servlet-mapping>
<servlet-name>MyServer</servlet-name>
<url-pattern>/go/*</url-pattern>
</servlet-mapping>
If a browser submits http://localhost/MyServer/go?P=123 the servlet is launched and all is well. However, I'd like to only launch that servlet if the URL is exactly as just shown. Unfortunately, right now if the URL is http://localhost/MyServer/go?P=AnyDarnThing the servlet still launches. I have tried setting up the following:
<url-pattern>/go?P=123</url-pattern>
but this results in The requested resource (/MyServer/go) is not available.
I've tried numerous variations (quoting the string, ...) on the above URL pattern but I always get the above error. I notice that if I (for debugging purposes) drop the "?" as in
<url-pattern>/goP=123</url-pattern>
I no longer get the error message and the server launches (but, of course, it doesn't respond to the "query string" because it's not properly formed.) This suggest to me that the "?" is causing a problem in the mapping. I've tried replacing it with its URL special character equivalent as follows:
<url-pattern>/go%3FP=123</url-pattern>
but this gives the same result just described above when I tried dropping the "?" altogether.
I realize I can let the servlet get launched when any query string is submitted and then "ignore" the request for all but the one I care about but there is a reason I'd prefer to not have the servlet launched to begin with. So, my question is, how can I configure the servlet so that it is only launched when a specific query string is included?
Thank you.
You can't do that. The url-pattern is pretty limited.
If you want to have distinct actions taken based on a GET parameter, you can do that manually. In the doGet() method of the servlet have a simple if-clause and invoke different methods depending on the query string / get param.
You can't do that using URL patterns.
You can achive this using filters. Implement a filter which will forward to the Servlet only if the query params exists.
Here is the how the filter will look like:
public class ServletAcessFilter implements Filter
{
public void init(FilterConfig filterConfig) throws ServletException
{
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException
{
//validate the request, check if the request can be forwarded to servlet.
if(request.getParameter("P").equalsIgnoreCase("123")){
filterChain.doFilter(request, response);
} else {
//write what you want to do if the request has no access
//below code will write 404 not found, you can do based on your requirement
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setStatus(404);
}
}
public void destroy()
{
}
}
Define the filter in the web.xml like this:
<filter>
<filter-name>ServletAccessFilter</filter-name>
<filter-class>com.ServletAcessFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ServletAccessFilter</filter-name>
<url-pattern>/go/*</url-pattern>
</filter-mapping>
To add to Bozho response, you may also try to move to Clean URLs
This will greatly increase your options in terms of URL pattern matching, and, in particular, may significantly ease configuration of a fronting reverse proxy if you ever need one.