I have my java project web application. I am usning struts 2. Across the application , i make the action URL and submit it then response jsp is shown as
result but URL does not get changed in address bar(which is expected). But one jsp when i submit the action to create the employee , i see the create
customer action URL in address bar which i don't expect. I am using post method. I debugged the issue but found nothing special in request/response
object for this http request?
Seeing the address of the action you posted to in the browser address bar is expected behavior.
What you should do is use the Post-Redirect-Get pattern, so that the user can successfully refresh the page or navigate through historywithout any problem. This will also have the side-effect of displaying the URL of the action you redirect to after the creation, rather than the URL of the creation action itself.
Related
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.
I think the title above is a bit confusing.
What I'm trying to achieve:
I have a jps page(located in WEB-INF) with a hyperlink in it that will call another jsp (in WEB-INF) via servlet.
I understand that this can be achieved using the following:
Go to this page
But because there will be lots of hyperlinks, my idea was to have a general servlet(OpenPagesServlet) to handle all those pages.
Something like this:
JSP page:
<% request.setAttribute("page", "page1.jsp");%>
Page 1
OpenPagesServlet in doGet method:
String page = (String) request.getAttribute("page");
request.getRequestDispatcher("/WEB-INF/" + page).forward(request, response);
I tried the code above and I get:
HTTP Status 404 - Not Found
type Status report
messageNot Found
descriptionThe requested resource is not available.
But if I try with session.setAttribute / sesion.getAttribute the code works fine, but I don't want to have sessions on each time I click on hyperlinks.
The other approach I found was to use:
Page 1
and inside the servlet:
String page = (String)request.getParameter("value");
request.getRequestDispatcher("/WEB-INF/" + page).forward(request, response);
It worked, but this approach is not good because the page can then be accessed directly using the url:
http://localhost:8080/WebApp/OpenPagesServlet?value=page1
So...my question is why request.setAttribute/request.getAttribute is returning 404?
Is there a different approach to achieve what I'm trying to do?
An HttpServletRequest and its attributes only live for the duration of one HTTP request/response cycle. After yo've set the attribute in the JSP, the JSP is rendered and sent as part of the HTTP response body. The Servlet container considers the request handled and clears its attributes. The attribute is now gone.
It is therefore no longer available in the next request that arrives after the user clicks the link.
The session attribute or request parameter is fine. Consider looking into the Front Controller pattern.
Also, consider using the core tag library (in particular the url tag) instead of scriptlets for constructing your links.
When I submit a form to the browser,the form is submitted twice.The access log shows there are two requests arise at the same time.Two different threads executing it.
The thing is,the first request contains the attribute values that the user entered while the second request call contains only null values in request object.
Not all the times this issue occur.It happens only sometimes and not reproducible at all.Both in IE8 and IE9,I got these issues.
Do anyone know why does it happen?
Maybe the problem is that you are using submit button and document.forms[0].submit within the javascript onclick event handler .
Thus action is called twice:
First time by
document.forms[0].submit
Second time by
submit button action
Do you use struts1 or struts2? Anyway, they both have a mechanism to avoid repeat submit: token.
For struts1, you need call saveToken() in the first action (the action for form page), and 'html:form' tag of struts will automatically add this token to your page; in your submit action (the action which dealing form), invoke isTokenValid(request, true), and this will validate the token from your page & your session.
For struts2, add the interceptor ref token for your submit action, and add 's:token' tag in your form page.
The above solutions restrict repeat submitting in server side, that the second request will cause a exception and handled as invalid request. But if you wanna restrict this in UI side, you need some javascript, like: when you click the submit button, disable it to avoid repeat submitting.
Ok, so I've got an interesting case of login page redirection going on.
My webservice has a login page (login.html) with some javascript to handle logging in and redirecting to a hardcoded 'default' page. The webservice is written in Java with a servlet filter handling redirection if a user is unauthenticated (so if a user tries to access domain/statistics without being logged in, they are directed to domain/login.html). The redirection from the protected services works: I can redirect to the login page and once a user is authenticated, redirect them to a default page. I am having issues, however, redirecting to the previous page.
I know this is usually handled with the argument document.referrer in the Javascript, which I have tried, but due to the Java's redirection with response.sendRedirect, the Referer header is not sent.
How can I get these two aspects to redirect to the previously called page? Is it something I need to add on the Javascript side, the Java side, or both?
What I've done is to drop the original (redirected) URL into a hidden input field on the login form. The code that does the authentication should just check that parameter, and if it's not empty it can redirect after establishing the session.
You have to be careful doing this to prevent XSS attacks etc., but it's not that hard and it works just fine.
In my framework (Stripes), I can push the original URL (taken from the HttpServletRequest object, a combination of the servlet path, the "path info", and the query string) into a special holding box that will cause the framework to give it back to me on the next request as a parameter. Without that, the simple thing to do is add the URL as a parameter when you redirect. Just URL-encode the original attempted URL and tack it onto the redirect URL with some parameter name. Then, on your login page, you just check for it:
<c:if test='${not empty param.attemptedUrl}'>
<input type='hidden' name='attemptedUrl' value='${fn:escapeXml(param.attemptedUrl)}'>
</c:if>
Then your login action will get that parameter too when the login form is submitted, and it can act on it as appropriate.
Send Redirect will ask to the client to repeat the request to the resource you choose. Have you think of Spring Security with minimal configuration you can achieve this quite easily.
Take a look at this:
http://static.springsource.org/spring-security/site/docs/3.0.x/reference/ns-config.html
My title maybe confusing so please read on. I'm using the following technologies if you may. Spring, Hibernate, JSF (RichFaces), MySQL, Internet Explorer.
I have a List of items which is displayed in a RichFaces datatable like so:
item a
item b
item c
item d
item e
On the same page I have the following buttons: search, edit, add, delete and new.
When an user enters a search string, e.g. "item c", and press search button, then it displays a list of matching items, e.g:
item c
When the user presses the new button, the request will be redirected to another page using:
FacesContext facesContext = FacesContext.getCurrentInstance();
facesContext.getExternalContext().redirect(page + ".jsf" );
When the browser back button of IE is been pressed on that page, the page displays "web page expired". What is this and how can I avoid this?
web page expired
You will get this error when you're trying to obtain a non-cached POST request from the browser history. This behaviour is fully expected. To fix this "problem", you need to either turn the cache on or to replace POST by GET.
Enabling the browser cache is actually easy: just remove the Cache-Control: no-cache and related headers from the HTTP response of the POST request in question. The enduser will then only get a warning dialog that the POST data will be resent to the server, which in case of fully non-idempotent requests like placing an order or deleting an item is really not desirable. Replacing POST by GET is then a better solution. Getting searchresults (like as Google does) should really be done by GET.
Replacing POST by GET isn't easy in JSF prior to version 2.0. Best what you can do is to fire a redirect after the POST and pass the data of interest as request parameter which you retain from #{param} as managed property (more recommended) or store the data of interest in session scope (not recommended). A completely different alternative is to replace the JSF <h:form> by a simple HTML <form action="searchresults.jsf"> and do the search job in a #PostConstruct method in the backing bean associated with searchresults.jsf, after the submitted query has been gathered as managed property or from request parameter map.