Servlet 3.0 include html page - java

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 ?

Related

how to rewrite the url in java web application?

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.

what is in background of html submit form?

I'm trying to figure out what really happens when html submit form button is clicked.
I suppose it generates some kind of http request (similar to ajax get or post call) which has data in http body and is sent to address specified in action field.
1) Am I right?
2) I've seen many ways of processing forms with PHP or ASP on server side. Can I process it with Java REST Application using e.g. Jersey? Is submit form capable of hitting REST if I put right URL in action field?
Thank You.
By submitting the form in HTML you basically tell the browser to generate a normal HTTP request, usually POST or GET, for an URL defined in tag with form fields attached according to the specified method either appended to the URL or included in the request data.
There is nothing really special or different from a "normal" HTTP request, in fact you can manually "submit a form" by appending form keys and values to the URL in your browser and navigating to it in case of GET method.
Summarizing:
1) Yes, you are right.
2) From what I've just read (never used REST personally) a REST application is implemented by a servlet mechanism and uses HTTP protocol, so it should be possible to write a REST application for processing HTML forms if the form points to this application's URL.

How do I send a list to the jsp that requested it?

Let us suppose there is a jsp that needs to display the list of files shared shared by a particular IP. Client opens that jsp on his local server and the request is sent to a remote server to fetch the list.
Servlet on the server processes the request and fetches the list of files shared by that IP. Now how do the servlet send that list to the jsp page that requested it ?
JSP :
connection.openConnection(); // Connection sends IP as the query parameter to the
// remote servlet
Servlet :
doGet(..parameters..) {
list = getList(forThatIP);
// NOW HOW DO I SEND THIS LIST ?
}
One method that I thought was to send the whole data as a query string to a servlet on the client side(running a server such as tomcat) and then stash that list onto some file.Later jsp can parse the file and display the data. But that doesn't seem to be a good option.
Note: JSP is invoked when a servlet forwards after successfully sending the IP to remote servlet
You can use request.setAttribute() in the Servlet. Then you can use a JSP tag to retrieve the value in JSP. Investigate a bit on that.
EDIT :
In the Servlet doGet method, you can set the an attribute, say listOfFiles as:
resquest.setAttribute("listOfFiles",list);
Then in the JSP you can retirieve it using the EL expression:
${listOfFiles}
which is an inbuilt feature of JSP.
Alternatively, you can access it using
<% request.getAttribute("listOfFiles")%>
but it is bad to embed Java scriptlets inside JSPs.
If you're passing complex data (lists etc.) over a connection, you can look into using JSON or XML. Your JSP code should be able to parse either easily with the right library.
Actually it depends on how the jsp is invoked.
Do you perform a post onto it ? Does the servlet perform a forward ? Or is a sendRedirect() ?
According to this there are many ways to send data to your jsp. One is using request attributes or better, using request scoped beans. One other can be posting some sort of rappresentation of your list as a post parameter (be it json, xml or some custom format of yours).
Another thing to consider is, what are you using ? JSF ? Some Spring library ? According to that there may be other better (or worse) ways to send datas.
If working with simple JSP/Servlet on a small project I'd personally go with the request.setAttribute() way, indeed this will force me to invoke the jsp via something like
request.setAttribute("myList", yourListObject);
request.getRequestDispatcher("yourjsp.jsp").forward(request, response);
then in the jsp you can:
<% Object myListObj = pageContext.getRequest().getAttribute("myList"); %>
When you call a servlet from code, the best way is to use an HttpServlet and mimic the browser behavior.
Passing the data in the URL is a GET request. Useful only with relatively small chunks of data, but the semantics look like you want ("get a bit of data"). Something like http://myremoteserver.com/myServlet?ip=.... You will need a proper encoding of the parameters (the Java API can handle that).
Passing the data by writting into the stream will be a POST request. It has no limit in the data passed to the server, but the semantics is different ("change something in the system"). You could pass your data as a parameter inside the contents written, I am not really sure how to decode that. Another alternative is using a Servlet (no HttpServlet) and just treat the raw data.
In both cases the response will be returned in the connection output stream. You can use whatever format you like (an standard one like JSON will probably be best, even that defining your own XML). In this case, a viable alternative would be filenames separated by a 'safe' character (like \n or |). Quick, but it will be less flexible in the future.
I would go for a GET request and JSON encoding.

Easiest way to submit a form to ServletUnit using something like WebRequest in HttpUnit

I would like to programmatically create a form with fields etc, however i have not been able to find a public factory etc to create a WebForm(class). Once this is done i would like to then submit the form and have my servlet do stuff with the form.
One approach i noticed the tests use is to create a PseudoServer which is a simple socket server. The tests then eventually make a request to some url which replies with some arbitrary html which includes a form. The problem with this is i cant register my own custom servlet to do stuff.
Im thus stuck between wanting a form but being unable to create one, if i wish to unit servletunit.
Is there a way to submit forms to a servlet inside servlet unit ?
Is there a way to combine parts of httpunit the form submitting stuff w/ servlet unit ?
Im guessing probably not because it(httpunit) wants to submit a form via socket and servletunit does not use sockets at all.
As per Andrey's suggestion and my past experimenting i have attempted to to call numerous methods on WebRequest to attempt to communicate the stuff that exists in a form being posted to a server.
selectFile() - to pick the file to be uploaded
setHeaderField() to set content type/charset/encoding.
You can use PostMethodWebRequest to send POST request to any HTTP URL:
WebRequest request = new PostMethodWebRequest(serverUrl);
And then just set form parameters directly in the request object:
request.setParameter('name', 'user1');
request.setParameter('password', '123456');

Servlet request blocking

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".

Categories