Stop form submit after page refresh with DispatcherServlet - java

I use request.getRequestDispatcher(url).forward(request, response) method in my controller !! I am in trouble. (I know that dispatcher make internal redirect, a forward reuses the current request), when I fill in a form and send request to controller that computes some logic and after forward to some simple page. If I push F5 in browser on my simple page (refresh page) my request will perform again. How to prevent this situation ??

RequestDispatcher will keep request attributes and forward page with same request, that is why if you refresh page controller gets same request and process it again. Use SendRedirect instead.

Related

Why does servlet name stay in url after RequestDispatcher.forward?

I am making a JSP/Servlet web app which starts with log in page.
After user enters log in information, a servlet, called LoginServlet, processes the data and if the log in is successful the servlet redirects user to MainPage.jsp like this:
RequestDispatcher rd = request.getRequestDispatcher("MainPage.jsp");
rd.forward(request,response);
It works. It takes me to MainPage.jsp, only the URL is NOT:
http://localhost:8080/RestauRec/MainPage.jsp
it is:
http://localhost:8080/RestauRec/LoginServlet
It is not an actual problem, but still, I want to know why this is and how can I change this?
Note: I don't know if it matters or not but, in the action attribute of the form element (in the log in page) I place LoginServlet. Like this:
<form action="LoginServlet" method="POST">
Thanks in advance!
forward is an action that happens within a single request-response cycle. It uses the forward-to resource to complete the response.
Your browser sends a single request to /someUrl and your server handles it, returning a response.
It is not an actual problem, but still, I want to know why this is and how can I change this?
You'd have to make your client, the browser, send a different request to another URL, possibly because of a redirect.
forward() method won't change the url. sendRedirect() in HttpServletResponse do change the url as well.
response.sendRedirect("MainPage.jsp");
Remember that a new request gets hit to the container when you do redirect. That means all the previous data vanishes and you'll get a brand new request.

Forward request to servlet using jquery which in turn forwards to jsp?

I have a js file and based on the below condition I need to display a message or forward the request to servlet which in turn forwards to jsp.
var isInIframe = (parent !== window),
if (isInIframe) {
//Forward request to servlet
}else {
//Display Access denied message
}
I can call a servlet using jquery ajax. But how can I forward request to servlet? once the request is forwarded to servlet then servlet will load some property files and forwards request to some.jsp as below.
//Keeps some values using request.setAttribute() then forward the request
request.getRequestDispatcher("/WEB-INF/some.jsp").forward(request, response);
How can i do that?
Thanks!
You can use Session for sending some objects to servlet. Because session remains same for the user throughout the application.
JQuery/Javascript does not "forward" requests to web applications. It makes new requests via AJAX or redirects. JQuery itself does not handle HTTP requests.
You need to make an AJAX request for this. I assume that JSP is the presentation layer of your web application. So just make an ajax request to your web app using the JQuery $.ajax() method..
You can handle the response using the AJAX callback function
Servlet and jsp are server-side components. The Server receives HTTP requests and dispatches a Servlet to handle them by producing a corresponding HTTP response for each of them, some times with the help of a jsp.
Javascript is a client-side component. It runs in the browser. When the javascript runs, the HTTP response containing the HTML you see in the browser has already been sent, so the Servlet is completely out of the picture. You cannot forward to it like you are imagining with
request.getRequestDispatcher("/WEB-INF/some.jsp").forward(request, response);
What you can do is use ajax to construct and send a new HTTP request that will be handled by a Servlet.

Send response and request from JSP to servlet

How can I send my response and request object from a jsp file to a servlet by code? I don't want to submit a form or so.
I tried it with:
response.setRedirect("my page"):
But then it says:
Exception in thread "main" org.apache.http.client.HttpResponseException: Moved Temporarily
at org.apache.http.impl.client.BasicResponseHandler.handleResponse(BasicResponseHandler.java:68)
at org.apache.http.impl.client.BasicResponseHandler.handleResponse(BasicResponseHandler.java:54)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:945)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:919)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:910)
at com.xx.xx.client.Client.sendPOSTRequest(Client.java:185)
at com.xx.xx.client.Client.main(Client.java:46)
As clarification: I have a client that sends a post request to a JSP file. This JSP file parses a file and puts the needed information into the session. I want to call a servlet from this jsp file to add something into the database. I think this error code is thrown by this line String responseBody = httpclient.execute(httppost, responseHandler);
You can just use <jsp:include> on a servlet URL.
<jsp:include page="/servletURL" />
The servlet doXxx() method will just be invoked with the current request/response. Note that the servlet cannot forward to another JSP afterwards. It has to write directly to the response, or to set some request/session attributes which the JSP can intercept on after the <jsp:include> line.
Note that this is bad design. You're abusing a JSP as a front controller. It should be the other way round. The servlet should act as a front controller and the JSP should act as a view. The client should send the request to the servlet URL directly instead of to some JSP file. The servlet should perform the business job and finally forward to a JSP to let it present the results in HTML. See also our servlets tag wiki page for some Hello World examples.
you can use the RequestDispatcher forward(ServletRequest request, ServletResponse response)
Forwards a request from a servlet to another resource (servlet, JSP file, or HTML file) on the server.
You can do it like this:
ServletContext context= getServletContext();
RequestDispatcher rd= context.getRequestDispatcher("/YourServlet");
rd.forward(request, response);
UPDATE
Also note on your code that you have response.setRedirect instead of response.sendRedirect(...) but note that this method will not work as you want it to because it just asks the browser to make a new request to your servlet rather than forward your request and response object to that servlet . See RequestDispatcher.forward() vs HttpServletResponse.sendRedirect() for more info

Servlet redirect doesn't display requested page

I have a page - lets call it page X - where I do an ajax call that populates my table constructed with jqGrid. So here I call localhost:8080/servlet/ajax/Data.json which is a servlet.
Now, if the page expires and the user still wants to access the table (search data for instance) I would like to redirect the request to the Login page.
The ajax call calls the Data.json servlet that is not in the same servletcontext as my Login page (which is localhost:8080/servlet/myapp), therefore I cannot use servlet forward (I am using JBoss 4.2 and I can only forward in the same servletcontext).
I have tried to redirect with sendRedirect, which is able to call the Login page that is actually executed but not displayed. And this is where I got lost. My Login page is executed and I still see page X.
I have tried to write the returned HTML (from Login page) into the response of page X (I also set the Content-Type to text/html). The HTML is returned in the response, but not displayed.
I am using Apache Turbine which is another servlet that retrieves a page when requested.
Do you have any ideas? I don't know what to do.
It looks like your servlet at servlet/ajax/Data.json is telling the AJAX request to redirect to the login page. Then the page is going to try to render the jqGrid table with the login page, which probably won't work.
You need to add code where you are making the AJAX call to servlet/ajax/Data.json to check to see whether the browser itself needs to be redirected. Either if the servlet returns a 302 redirect as a response, or if the servlet returns an error that's simply "SESSION EXPIRED", so the javascript on the browser's end that's making the AJAX call to the servlet knows the session has expired and to redirect the browser to the login page.
Ajax calls are asynchronous calls, sendRedirect call on ajax calls never be effective (ajax response always sends response to initiator).
You may need to use XMLHttpRequest status code to find out the page expiration and then use java script window.location to reset the browser url to login url.

Using JSF 2.0 / Facelets, is there a way to attach a global listener to all AJAX calls?

Is there a way to attach a global listener to all AJAX calls in JSF? Maybe through a phase listener or something?
Here is the conundrum... Lets say you're using f:ajax tags and something like apache shiro and you let your session expire. Then you come back and click a button that has an f:ajax attached to it. The server will respond with a 302 redirect to the login page.
The user sees nothing. They can repeatedly click and invoke the ajax call, but to them the app is just "dead."
So, my though is, is there a way to attach a listener to all ajax calls in JSF? If so, what I'd like to do is monitoring the response code. If it's a redirect, use a window.navigate to send them along their way.
I'm always open to hear how others have solved this problem!
Is there a way to attach a global listener to all AJAX calls in JSF? Maybe through a phase listener or something?
Yes, a PhaseListener can do it. A SystemEventListener also. A Filter also.
If you're inside JSF context, then you can check as follows whether the current request is an ajax request or not.
if (FacesContext.getCurrentInstance().getPartialViewContext().isAjaxRequest()) {
// It's an ajax request.
}
If you're not inside JSF context, e.g. inside a Filter, then you can check as follows whether the current request is a JSF ajax request or not.
if ("partial/ajax".equals(request.getHeader("Faces-Request"))) {
// It's a JSF ajax request.
}
Here is the conundrum... Lets say you're using f:ajax tags and something like apache shiro and you let your session expire. Then you come back and click a button that has an f:ajax attached to it. The server will respond with a 302 redirect to the login page.
The user sees nothing. They can repeatedly click and invoke the ajax call, but to them the app is just "dead."
Forcing a redirect on an ajax request requires a special XML response. When you're inside JSF context, then ExternalContext#redirect() already takes this implicitly into account. All you need to do is to write this:
FacesContext.getCurrentInstance().getExternalContext().redirect(url);
If you're not inside JSF context, e.g. inside a Filter, then you'd need to write the whole XML response yourself. E.g.
response.setContentType("text/xml");
response.getWriter()
.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
.printf("<partial-response><redirect url=\"%s\"></redirect></partial-response>", url);
To redirect a jsf ajax request you need xml as follows
<?xml version="1.0" encoding="UTF-8"?>
<partial-response>
<redirect url="XXX">
</redirect>
</partial-response>
Here XXX is url you want redirect to happen.
On ajax call redirect sent is not as above hence no redirect.
To get the desired result have a filter for all jsf request except few
pages(login page) and check session is valid and if it is really jsf
ajax call by checking header "Faces-Request", its value should be
"partial/ajax". If session has expired and is ajax request send above
xml as response.
It should work.

Categories

Resources