I have a Filter which scans all the request going through my application. I want to block a request if it requests for a specific url. I can able to check this and if the condition matches I am NOT doing chain.doFilter, but still the request moves to a black page. How can I block this request from going any further and stay in the current page - meaning user should not see any change to the screen that he clicked?
The HTTP status code 204 might work, but it is not guaranteed to work with all browsers:
204 No Content
The server has fulfilled the request
but does not need to return an
entity-body, and might want to return
updated metainformation. The response
MAY include new or updated
metainformation in the form of
entity-headers, which if present
SHOULD be associated with the
requested variant.
If the client is a user agent, it
SHOULD NOT change its document view
from that which caused the request to
be sent. This response is primarily
intended to allow input for actions to
take place without causing a change to
the user agent's active document view,
although any new or updated
metainformation SHOULD be applied to
the document currently in the user
agent's active view.
The 204 response MUST NOT include a
message-body, and thus is always
terminated by the first empty line
after the header fields.
(emphasis mine)
Alternatively, you can try one of these strategies:
Have the servlet return 307 (temporary redirect) back to the previous page using the HTTP Referer field. This approach might cause problems with caches and proxies.
Use ajax to load contents from your servlet. You will have to substitute direct links with JavaScript calls that initiate ajax calls to substitute part of your page. The URL in the browser will not change when you load contents this way, which may or may not be desirable. Many sites use a mix, including StackOverflow. Anything that should be "permalink-able" is navigated to via a regular link, but parts of each page is fetched lazily via ajax.
Finally, what's wrong with telling the user a link is off limits? Have the servlet return 403 (forbidden).
You can't. The browser has already made the request and it's out of its hands. You might be able to hack something where you return a little bit of javascript that silently "hits" the browsers "back" button, but that no doubt has all sorts of nasty issues with it.
But once the browser is has sent the request, the current page is "dead".
Related
On Form Submit my url changes from
localhost:8080/Workflow/admin/GetReports?fname=Form1
to
localhost:8080/Workflow/admin/EditReport
Form action is EditReport(Servlet Name).
Now on EditReport i perform the databse operations and forward the request to the GetReports?fname=Formname Servlet using Request Dispatcher.So that i am on the same page which is the first one (1) i started from.
Now Everything works fine on the .jsp page But the url remains unchanged that is the second one (2).
So how to rewrite the url i.e. from admin/EditReport to /admin/GetReports?fname=Form1
Are you using dispatcher.forward because you are setting some Attributes in
the Request?
If not, then you don't need to use Forward. Instead of that, use response.sendRedirect("url for GetReports?fname=Form1")
But If you are setting some Attributes in the request, then I am wondering if your workflow is a correct one because URLs like this "Workflow/admin/GetReports?fname=Form1" should Not be arrived upon after doing some processing. They should be simple HTTP GET requests only.
Reading below link , I could note that "doGet() allows bookmarks".
http://www.developersbook.com/servlets/interview-questions/servlets-interview-questions-faqs.php : search "It allows bookmarks"
Can anyone tell how and what is the use of it ?
All the parameters of GET request are contained in the url so when you are requesting for a resource using GET request, it can be formed using request URL itself.
Consider an example www.somesite.com.somePage.jsp. This generates a GET request because we are asking for a resource somePage.jsp.
If you are asking for a resource, then it is the GET request.
GET requests are used to retrieve data.
any GET request calls the doGet() method of servlet
GET requests are idempotent, i.e. calling the same resource again and again do not cause any side effects to the resources.
Hence, a GET request can have bookmarks
EDIT :-
As suggested by Jerry Andrews, POST methods do not have the query data unlike GET requests to form the resource properly with the help of only url. Hence they are not bookmarked.
It means that If you bookmark the URL of the servlet that has doGet() implemented, you could always get the same page again when you re-visit. This is very common when you have searches, link for products, news, etc.
I have an idea to make something pretty sweet but I'm not sure if it's possible. Here is an example of a very basic ajax function that I might use to establish a connection a server...
function getFakePage(userId)
{
var ajaxObject, path, params;
ajaxObject = getAjaxObject();
params = "?userId=" + userId
path = getInternalPath() + "someServlet" + params;
ajaxObject.open("GET", path, true);
ajaxObject.send();
// On ready state change stuff here
}
So let's say I have a URL like this...
https://localhost:8443/Instride/user/1/admin
And I wanted to use javascript to redirect the user to this this URL. Normally I would just do this...
window.location = "https://localhost:8443/Instride/user/1/admin";
But my idea is to create a javascript (no js frameworks please) function that could combine the ajax code with the window.location code. Basically what I would like to accomplish is to create a connection with the server via ajax, send a servlet on that server the url I would like the user to be redirected to, and then redirect the user to that URL. So that for however long it takes the user to connect to my server from wherever they are in the world they see a loading icon instead of a blank white page.
So to clarify exactly what I am trying to accomplish; I do not want to put window.location within the success of my ajax function (because that would be encompass two round trips), and I do not want to return a huge chunk of HTML for the requested resource and add it to the page. I want to establish a connection to the server with ajax, send a servlet the URL the user wants to go to, and then somehow override the ajax function to redirect that user. Is this possible?
And I know some of you might think this is stupid but it's not when you're talking about overseas users with slow dial up connections staring at white pages. If it's possible, I'd love to hear some insight. Thank you very much!
First, let me say that the best solution is finding what is causing the slowness and fixing it.
Now as to your question, yes you could do it. You could even shoehorn it onto an existing application. But it wouldn't be pretty. And it comes with it's own set of problems. But here are the steps:
Browser calls ajax cache service requesting "somepage.html"
Browser loads loading icon
Server creates somepage.html and caches it in a temporary cache, (ehcache or other library would be good, probably with file backing for the cache depending on size)
Server responds to ajax request with ID for cached page
Browser now redirects to "somepage.html?cacheId={cacheId}" where the id is from the ajax call.
Server uses a filter to see if any cache can be served up for the page instead of the actual page, thus speeding up the request.
Having said that, it would be better to just have the new page load quickly with a loading icon while it did any of the heavy lifting through ajax.
You can't do an AJAX request and a location change in one. If you want to do only one request you have to choose one of those methods. ie. return some data and replace content on your current page, or load a completely new page.
It doesn't make any sense to want to want to do both. What you could want is stateful URLs; where your URL matches the content displayed, even if that content comes from an AJAX request. In that case an easy solution is the use the # part of the URL which you can change freely (window.location.hash). Some modern browsers support changing the whole URL without causing the page to reload. I've used # with great success myself.
I have a home-grown MVC implementation. A ControllerServlet like so:
/controller?cmd=EditUser&userid=55
From this URL, the controller creates a EditUserCommand.class instance and calls an execute() method which returns the result page (ex. user.jsp) to display.
The controller servlet then does a ...
getRequestDispatcher(resultPage).forward(request, response);
... and the resulting page is shown.
One of the things the controller does is set messages (error, info, and so on) as request attribtues. For example:
request.setAttribute("infoMessage", "User was edited successfully.");
And that message gets pulled out of the request in the user.jsp page and displayed.
Works fine.
Now here comes my problem.
Sometimes my commands don't return a page like user.jsp but return a URL like cmd=ShowUser&userid=55 for the result. This is because there might be things I want to check before displaying the final page, like permission to view the user and so on.
When I do this the "infoMessage" I placed in the request never appears because the result is a URL that makes a new call to the servlet, which is a new request. The new request doesn't maintain the request attributes from the first request; which makes sense, I just didn't forsee this happening.
How can I make my request variable "stay alive" until it's actually displayed on the final page that results from the original request?
Any suggestions or advice are appreciated. Just FYI, I can't re-write the entire app to go to something like Struts, Spring MVC, of JSF. It's not an option.
Thanks!
Rob
redirect generally looses request data because of brand new request from browser. One possible approach may be append your message to url string as attribute and read it when you need.
Based on your EDIT: After your edit also, my answer make sense. But, only one correction is, it is not brand new request because forward happens on server side.
Have you tried using a RequestDispatcher instead of a Redirect?
RequestDispatcher dispatcher = request.getRequestDispatcher("/myNextPage.jsp");
dispatcher.forward(request, response);
You may be giving a simple example, but your control flow causes the "Resend" Error, perhaps? Basically, after making any change to the data, the controller must immediately do a "Get" via a redirect and the screen should be displayed completely stateless.
Please take a look:
http://en.wikipedia.org/wiki/Post/Redirect/Get
As such, Attributes are not a great help. What you may want to consider is, maintaining a Bean/Object for every login user, and persist this object in a LRU cache (JCache or MemcacheD), and retrieve it on every entry to the application. Once you have that, you can maintain a pseudo-state such as previous results in that object.
In any case, using Attributes to retain state will severely constrain your options. You need to have a more generic flexible routing-independent mechanism.
I'm trying to achieve the following behavior using the Servlet 3.0 API:
send an inital html page
send subsequent responses that update the page
This all works except the only way I could send the initial page without getting the response committed is by manually writing using the HttpResponse Writer...
I was wondering if there is a way of using something similar to RequestDispatcher#include with an html page without running into problems with the AsyncContext. Some things I tried until now and didn't work:
use AsyncContext#dispatch: as much as I read on the Internet, it is destined for sending the final response to the container in order to render it
use RequestDispatcher#forward: getting IllegalStateException due to trying to write more content in the OutputStream
use RequestDispatcher#include: if I initialize the AsyncContext before calling this method, request.isAsyncSupported returns true, after calling the method, it returns false. I read that it calls flushBuffer() and sets the commit flag to true on the response
Also, in the Servlet 3.0 spec there are some lines mentioning that dispatching from async servlet to normal servlet is possible but will commit the answer. I believe a static html page belongs to this category...
If you have any ideas of how an elegant include can be done without affecting the ability to still send streamed responses back to the client, please let me know.
Thanks
One solution (not the only one): if it's just a html page, then write the html page itself in html and do ajax calls to the serrvlet that needs to provide the updates.
use static elements on the page that store data and use requestdispatcher.
Or you could also just simply refresh the entire page with such an arrangement using response.setHeader("refresh", "5; URL=officer.html").
I really don't understand your need to send multiple requests without the response being committed to a servlet. are you trying to interact with a serving thread multiple times ?