I'm redirecting to another page:
String uri = "../test/planOutput.jsf?job_id=121250";
FacesContext.getCurrentInstance().getExternalContext().dispatch(uri);
It works, but the URL doesn't change,
I must see the new URL with the parameter.
What is the solution?
You aren't redirecting the request to a different target at all. You are dispatching the request to a different source. Use ExternalContext#redirect() instead of ExternalContext#dispatch().
FacesContext.getCurrentInstance().getExternalContext().redirect(uri);
A redirect basically instructs the webbrowser to fire a new HTTP request on the given URL. That's also why you see the URL change being reflected in webbrowser's address bar. A dispatch basically instructs the webserver to use a different source for the current request/response. Since this happens internally and does not end up in a new HTTP request, the webbrowser know nothing about the change and the address bar won't be changed.
Related
My scenario is like this:
I'm building a website where I'm posting an ad regarding a topic. So, after the form filling of ad, the request goes to a REST service class as:
http://localhost:8080/cloudproject/postadvaction?title=tution&tag=tution&description=tution+%401000+%2F+month&category=TUTOR&location=indore
Here, the details of ad go in the database which is MongoDB. After all of this is done I'm redirecting to the profile page of user using Viewable model of jersey, where he can see all the ads posted by him. It is done as:
return new Viewable("/profile.jsp");
After this the response is redirected to profile page of the user.
But the problem is that, on redirecting the response to simply profile.jsp, the URL in the address bar has not changed to http://localhost:8080/profile.jsp, instead, it has remained the same as mentioned above. So, when user refreshes the page, the request of same ad post triggers and the whole process is followed again. Since, database is MongoDB, same ad is stored twice in it and same is displayed on the profile page of user with 2 identical ads.
So, how can I redirect to profile page without having the address of servlet in address bar?
Update: The question is related to PRG technique & Duplicate Form Submissions and not to just redirection.
See Post/Redirect/Get
When a web form is submitted to a server through an HTTP POST request, a web user that attempts to refresh the server response in certain user agents can cause the contents of the original HTTP POST request to be resubmitted, possibly causing undesired results, such as a duplicate web purchase.
To avoid this problem, many web developers use the PRG pattern[1] — instead of returning a web page directly, the POST operation returns a redirection command. The HTTP 1.1 specification introduced the HTTP 303 ("See other") response code to ensure that in this situation, the web user's browser can safely refresh the server response without causing the initial HTTP POST request to be resubmitted. However most common commercial applications in use today (new and old alike) still continue to issue HTTP 302 ("Found") responses in these situations.
With Jersey you can use
Response.seeOther(URI) - Create a new ResponseBuilder for a redirection. Used in the redirect-after-POST (aka POST/redirect/GET) pattern.
You just need to change your method signature to return a Response and return the built Response
return Response.seeOther(URI.create(...)).build();
Also stated about the URI parameter
the redirection URI. If a relative URI is supplied it will be converted into an absolute URI by resolving it relative to the base URI of the application (see UriInfo.getBaseUri()).
This question already has answers here:
RequestDispatcher.forward() vs HttpServletResponse.sendRedirect()
(9 answers)
Closed 6 years ago.
I have got a problem with my page jump when I use JAVA,
if I use:
response.sendRedirect("login.jsp")
then I get this url: http://localhost:8080/login.jsp
But if I use
request.getRequestDispathcer("login.jsp").forward(request, response)
then I get this url: http://localhost:8080/Shopping/login.jsp (the "Shopping" is the name of my module).
What's the difference?
To simply explain the difference,
response.sendRedirect("login.jsp");
doesn't prepend the contextpath (refers to the application/module in which the servlet is bundled)
but, whereas
request.getRequestDispathcer("login.jsp").forward(request, response);
will prepend the contextpath of the respective application
Furthermore, Redirect request is used to redirect to resources to different servers or domains. This transfer of control task is delegated to the browser by the container. That is, the redirect sends a header back to the browser / client. This header contains the resource url to be redirected by the browser. Then the browser initiates a new request to the given url.
Forward request is used to forward to resources available within the server from where the call is made. This transfer of control is done by the container internally and browser / client is not involved.
forward
Control can be forward to resources available within the server from where the call is made. This transfer of control is done by the container internally and browser / client is not involved. This is the major difference between forward and sendRedirect. When the forward is done, the original request and response objects are transfered along with additional parameters if needed.
redirect
Control can be redirect to resources to different servers or domains. This transfer of control task is delegated to the browser by the container. That is, the redirect sends a header back to the browser / client. This header contains the resource url to be redirected by the browser. Then the browser initiates a new request to the given url. Since it is a new request, the old request and response object is lost.
For example, sendRedirect can transfer control from http://google.com to http://anydomain.com but forward cannot do this.
‘session’ is not lost in both forward and redirect.
To feel the difference between forward and sendRedirect visually see the address bar of your browser,
in forward, you will not see the forwarded address (since the browser is not involved)
in redirect, you can see the redirected address.
The main difference between the forward() and sendRedirect() methods is
that in the case of forward(), redirect happens at the server end and
is not visible to the client, but in the case of sendRedirect(),
redirection happens at the client end and it's visible to the client.
Other difference between Forward(ServletRequest request, ServletResponse response) and sendRedirect(String url) is
forward():
The forward() method is executed on the server-side.
The request is transferred to another resource within the same server.
It does not depend on the client’s request protocol since the forward () method is provided by the servlet container.
The request is shared by the target resource.
Only one call is consumed in this method.
It can be used within the server.
We cannot see the forwarded messages, it is transparent.
The forward() method is faster than sendRedirect() method.
It is declared in the RequestDispatcher interface.
sendRedirect():
The sendRedirect() method is executed on the client-side.
The request is transferred to another resource to a different server.
The sendRedirect() method is provided under HTTP so it can be used only with HTTP clients.
New request is created for the destination resource.
Two request and response calls are consumed.
It can be used within and outside the server.
We can see redirected address, it is not transparent.
The sendRedirect() method is slower because when new request is created old request object is lost.
It is declared in HttpServletResponse.
Which one is good? It depends upon the scenario for which method is more useful.
If you want control is transfer to a new server or context, and it is
treated as a completely new task, then we go for sendRedirect.
Generally, a forward should be used if the operation can be safely
repeated upon a browser reload of the web page and will not affect the
result.
1.redirect return the request to the browser from server,then resend the request to the server from browser.
2.forward send the request to another servlet (servlet to servlet).
Redirect and Request dispatcher are two different methods to move form one page to another.
if we are using redirect to a new page actually a new request is happening from the client side itself to the new page.
so we can see the change in the URL.
Since redirection is a new request the old request values are not available here.
HI,
This question is from previously answered question by BalusC. The excerpt of the answer as follows:
This happens only if under the covers
a forward by
RequestDispatcher#forward() takes
place. In a forward, the
servletcontainer basically reuses the
same HTTP request/response for a view
(JSP/XHTML page). It does not
force/instruct the webbrowser to send
a brand new request.
What this means is every new view is rendered using the forward. The following are my questions:
If the above is the case, then all the views displayed with the same request?. Because, we are always seeing the same URL in the address bar.
Is it that the values in the previous request is retained for the new request?
In this case, if every request is same then is it like storing in the session, for long time. I am bit confused on the view handling by JSF. Want to understand more internal work flow of JSF.
When we use the <redirect/> in faces-config.xml, will the URL in address bar get changed?
If the above is the case, then all the views displayed with the same request?. Because, we are always seeing the same URL in the address bar.
If it concerns a HTTP POST request and the JSF bean action navigates to a different view, then per saldo you will indeed have two different views in the same request. One for the initial view which is been used to gather/convert/validate the necessary request parameters and update the model values and other for the result view which is been used to show some result.
Is it that the values in the previous request is retained for the new request?
In a forward there's no means of a new request. It's the same request.
In this case, if every request is same then is it like storing in the session, for long time. I am bit confused on the view handling by JSF. Want to understand more internal work flow of JSF.
This is definitely not the case. As to your confusion, it may help to put JSF aside for a while and go playing with plain vanilla JSP/Servlet (which is what JSF is using under the covers). I think the following links may help in getting new insights about how basic JSP/Servlet works and how the average MVC framework on top of JSP/Servlet works:
Servlets tag info page
Design patterns Java web applications
When we use the <redirect/> in faces-config.xml, will the URL in address bar get changed?
Yes. A HTTP redirect sends a HTTP location: newpage.jsf header which in turn instructs the webbrowser to fire a new HTTP GET request on the given location. This get reflected in the browser address bar. You may want to install a HTTP debugging tool like Firebug or Fiddler2 to track HTTP traffic. You'll see that a forward happens inside the same request and a redirect comes with a new request.
If the above is the case, then all the views displayed with the same request?. Because, we are always seeing the same URL in the address bar.
if the url is the same in the web-browser then there can be two cases. either the same request is being forwarded as he mentioned OR new GET request is issued with same URL [which is lesser the case]
Is it that the values in the previous request is retained for the new request?
request life cycle will be from request to response. so after response all the managed bean with request scoped will get destroyed.
When we use the in faces-config.xml, will the URL in address bar get changed?
Yes it will instruct browser to issue new GET request for new URL.
As I understand it and have used it, AJAX is used to make requests from the client to the server and to then update a HTML DIV on the client with new content.
However, I want to use AJAX from a client to a servlet to verify the existence of a URL. If the result is bad, I can set an error message in the servlet and return it to the client page for display.
But does anyone know if, in the case of a positive result, I can have my servlet automatically display another (the next) page to the user? Or should that request be triggered by Javascript on the client when the positive results is received.
Thanks
Mr Morgan.
Since your ajax call is executed in the background the result returned by the servlet, returns to the ajax call, which should then act accordingly to the result. e.g. trigger the display of another page. (Which could have been already in the ajax response and then you can show it in a div or iframe or ...)
As per the W3 specification, XMLHttpRequest forces the webbrowser to the new location when the server returns a fullworthy 301/302 redirect and the Same Origin Policy of the new request is met. This however fails in certain browsers like certain Google Chrome versions.
To achieve best crossbrowser result, also when the redirected URL doesn't met the Same Origin Policy rules, you would like to change the location in JavaScript side instead. You can eventually let your servlet send the status and the desired new URL. E.g.
Map<String, Object> map = new HashMap<String, Object>();
map.put("redirect", true);
map.put("location", "http://stackoverflow.com");
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
resposne.getWriter().write(new Gson().toJson(map));
(that Gson is by the way Google Gson which eases converting Java Objects to JSON)
and then in the Ajax success callback handler in JS:
if (response.redirect) {
window.location = response.location;
}
In your success call back (on client), set the self.location.href to new URL.
HTML is a "pull" technology: Nothing gets displayed in the browser that the browser hasn't previously requested from the server.
Hence, you don't have a chance to "make the servlet automatically display a different page." You have to talk your browser (from JavaScript) into requesting a different page.
I'm trying to forward a request to another URL which includes the hash symbol ('#'):
request.getRequestDispatcher("/some/path.jsp#somehash").forward(request, response);
Tomcat, however, tells me that "the requested resource is not available". If I remove the hash from the URL, everything works fine. Are hashes not allowed or am I not treating them right?
The # symbol is a browser thing, not a server thing. When you type a URL with a # into the browser, the browser doesn't send that part to the server. It sends the URL without it, then jumps to the named anchor when it gets the page back.
When you ask the container to get that URL for you, it doesn't treat the # any differently to any other URL - it has no special meaning for it, so it looks for a JSP page called /some/path.jsp#somehash, which of course doesn't exist.
You'll need to keep that jump-to-anchor logic on the client somehow. Perhaps you could put some javascript on the resulting page to scroll to that point in the document.
URL fragments are purely client side. The RequestDispatcher#forward() is entirely server-side. The in the forward given URL won't be sent to the client side. You can however redirect to the given URL using HttpServletResponse#sendRedirect(). The URL fragment will then be sent to the client side and reflected in browser address bar as well. Redirecting the request has however the disadvantage that the current request will be garbaged and a brand new one will be created. If that's not affordable, then you'll indeed have to look in the JavaScript corner for the solution.