I have a login servlet with the URL mapping "/Login", which manages the user input and the login procedure. However, when the user logs in, the web site is directed to the URL:
http://localhost:8080/pilot_1/Login
instead of
http://localhost:8080/pilot_1/checklistallitem
It is to mention that the first URL works fine, it shows all the data, but I am not sure why the URL does not show up as desired. Here's my doPost method of the Login Servlet.
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String username = req.getParameter("j_username");
String password = req.getParameter("j_password");
if (users.containsKey(username)){
if ( users.get(username).equals(password)){
req.getSession().setAttribute("active_window", "Checklist");
req.getSession().setAttribute("current_team", "allteams");
getServletContext().getRequestDispatcher("/checklistallteam").forward(req, resp);
}else{
JOptionPane.showMessageDialog(null, "Invalid ID or Password");
}
}else{
JOptionPane.showMessageDialog(null, "Invalid ID or Password");
}
}
This is the difference between a redirect and a forward. When you forward a request with a dispatcher the resolution and processing happens server side, then the final response is returned to the calling client. On the other hand, when you issue a redirect, there is an intermediate response to the client that basically tells it - 'Call this other URL to fulfill the request'. As a side effect the client will be aware of the URL of the new resource and will update the location bar to reflect it.
Because a forward is processed entirely on the server side the URL in the clients location bar does not change.
Related
This might be a duplicate, but I haven't found the answer that exactly resolves my problem... Sorry in advance if it's a duplicate.
I have an html form that takes a user name and password, and when I press Run request, it creates a post request to a servlet.
HTML page screenshot here.
The servlet itself doesn't need authentication. Instead, it uses the parameters to run another program in a process, which needs the user and password.
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String user = request.getParameter("user")
String password = request.getParameter("password");
String command = "cmd /c someprogram --user=\"" + user + "\" --password=\"" + password + "\"";
RunTime.getRuntime().exec(command);
...
}
But when I run this, the browser will show the http post request with the my password. Is there anyway that I can hide this?
RequestScreenshot
Thanks alot!!!!
To Simply hide from browser address bar, use POST instead of GET.
==========
If you really want to secure your password,then SSL is a must.
POST is not more secure than GET as it’s also send unencrypted.
SSL will cover the whole HTTP communication and encrypt the HTTP data send between the client and server.
Your HTML form element should have an attribute with method = post . (Formatting lacking as I'm on my phone)
I have a Java application server under the following URL:-
http://t4-dev.pta.com/gui
The user who lands to this page will be asked to login using CAS Server and the URL is returned back to http://t4-dev.pta.com/gui/ReturnLoginViaMax.
I have implemented a Servlet to handle this URL -
public class CasRedirectServlet extends HttpServlet{
public void service(HttpServletRequest req, HttpServletResponse res)
throws IOException, ServletException{
//RequestDispatcher rd = req
// .getRequestDispatcher("/test.jsp");
RequestDispatcher rd = req.getRequestDispatcher("banana/index.html#/dashboard/file/t4.json");
rd.forward(req, res);
//res.sendRedirect("banana/index.html#/dashboard/file/t4.json");
}
}
so, now if the user hits the above servlet he will be redirected to another json file:-
banana/index.html#/dashboard/file/t4.json
This works if the If I do a sendredirect but when I use requestdispatcher it fails
message /gui/banana/index.html#/dashboard/file/t4.json
description The requested resource is not available.
I'm not sure why the above resource is not found.
It doesn't work because your path contains a URL token (the part following the # sign), which is a client-side thing interpreted by the browser only, while RequestDispatcher.forward() does a server-side internal forward and does not send the token to the browser.
If you want to use URL tokens in this way, your only option is to use sendRedirect(). This triggers a round-trip to the browser and updates the actual URL that the browser is accessing, thus giving the browser access to the URL token.
It is simply because forward and redirect are not the same at all.
When you redirect, you pass an URL back to the client browser. The browser interprets the given URL banana/index.html#/dashboard/file/t4.json and emits a request for URL /gui/banana/index.html, gets the page, and automatically scrolls it to the anchor /dashbord/file/t4.json (or just displays it if it cannot find the anchor).
But when forwarding, you ask the servlet container to pass the current request to the servlet able to serve the given URL and the servlet container cannot process the # part which is for a browser and gives you an error.
I'm having a problem with my authentication filter. When the filter redirects to the login page, all the previous page (main page) is displayed in the login page.
If I go to the login page manually it works fine.
Here is my filter:
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
HttpSession session = req.getSession(false);
String loginURL = req.getContextPath() + SiteMap.LOGIN_CONTROLLER;
boolean sessionCreated = session != null && !session.isNew();
if (sessionCreated) {
chain.doFilter(request, response);
} else {
res.sendRedirect(loginURL);
}
I also noted that when filter redirects to the login page the URL in browser bar stays the same. The main problem is that I get content from other page in the login page. I don't know where is the problem.
Changing the URl in browser did not depends on filter but it depends on how you are calling the page/servlet. You can call your servlet/jsp in two ways
RequestDispatcher : Transfers the control to other under the same request (Same URL)
Send Redirect : Initiates a new request (New Url)
Note : All that filter will do is a validation for the request
what is the value of loginURL that you are passing . Send a relative path.
I was having the exact same problem.
The real problem is that I and you both forgot to add the following line:
response.setContentType("text/html");
After adding this line my redirect works fine. Before this my servlet will stay on the
same page with a blank page (because nothing has been written to the response oputput stream).
Hope this may help others who is having this problem. It took me some painful minutes before test this possibility.
I'm working on servlet page that renders content based on geo-location, and I want to use both sendRedirect and forward together; e.g; you browse example.com/aPage.jsp from France; first I want the servlet to redirect you to example.com/fr/aPage.jsp and then forward you to the resources page.
This is what I have in my servlet:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
....
response.sendRedirect(REDIRECT_URL_BASED_ON_GEO);
// after redirect forward the resources page
RequestDispatcher view = request.getRequestDispatcher(RESOURCES_PAGE);
view.forward(request, response);
...
}
But I get:
java.lang.IllegalStateException: Cannot forward after response has been committed
I know the error appears because I can't use both sendRedirect and forward one after another, but I don't know how to achieve what I want (as described above) without this.
any help?
response.sendRedirect(REDIRECT_URL_BASED_ON_GEO);
// after redirect forward the resources page
After that line , Your response start writing to clinet.
And you are trying to add additional data to it.
The server has already finished writing the response header and is writing the body of the content, and which point you are trying to write more to the header - of course it cant rewind.
So,Thumb rule while dealing with servlet is
Finish your logic before redirect or forward add return statement.So execution ends there .
When you call
response.sendRedirect(REDIRECT_URL_BASED_ON_GEO);
you are sending your client a 302 HTTP status code with the location to redirect to. Your client then needs to make a new HTTP request to that location. Whichever Servlet is supposed to handle the path REDIRECT_URL_BASED_ON_GEO should then use the RequestDispatcher to forward to the resource described by RESOURCES_PAGE.
To better explain your exception
java.lang.IllegalStateException: Cannot forward after response has been committed
a committed response is a response where HTTP headers are already sent. If we look at your code
response.sendRedirect(REDIRECT_URL_BASED_ON_GEO);
After this line, you've already sent the response along with the headers (302).
RequestDispatcher view = request.getRequestDispatcher(RESOURCES_PAGE);
view.forward(request, response);
After these lines, you're asking the resource RESOURCES_PAGE to finish processing the request. That includes writing HTTP headers and body. But the request has already been processed and a response has already been sent, so it will fail, throwing the exception.
You have to be aware that a redirect is a complete response to the browser and the browser will in turn issue a new request to the url you redirected to. Even though you can't really sse it when dealing with the browser you always have to be aware that this is what happens.
Now, if you use the same controller for the second request you have to check wether a redirect is necessary or you can now do the forward instead.
if (!path.startsWith(locationPrefix)) {
response.sendRedirect(locationPrefix + path);
return;
} else {
RequestDispatcher view = request.getRequestDispatcher(RESOURCES_PAGE);
view.forward(request, response);
return;
}
Of course it would be nicer to have a distinct controller per request, but depending of url structure and framework this is not always possible.
Once you redirect, the servlet you're working on is no longer in control. You need to get the servlet that is the target of the redirect to recognize the correct condition to forward and then call forward there, with similar code:
RequestDispatcher view = request.getRequestDispatcher(RESOURCES_PAGE);
view.forward(request, response);
Even if it's the same servlet, it's a new invocation of the servlet's doGet( or other similar method.
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String text = "some text";
response.setContentType("text/plain"); // Set content type of the response so that jQuery knows what it can expect.
response.setCharacterEncoding("UTF-8"); // You want world domination, huh?
response.getWriter().write(text); // Write response body.
}
If I use this servlet , where request variable will have the url of the API of the website . Then how do I capture the response ? I would want to know what is the code to do that , and is this the right way to go about it when trying to build a JSP page that deals with interacting with an API of a website and showing data ?
You're confusing things. The HttpServletRequest is the HTTP request which the client (the webbrowser) has made to reach the servlet. The HttpServletResponse is the response which you should use to send back the result to the client (the webbrowser).
If you want to fire a HTTP request programmatically, you should use java.net.URLConnection.
URLConnection connection = new URL("http://example.com").openConnection();
InputStream input = connection.getInputStream(); // This contains the response. You need to convert this to String or some bean and then display in JSP.
See also:
How to use java.net.URLConnection to fire and handle HTTP requests