Can GWT client read the httpservletresponse with which it was invoked? - java

I have a Greasemonkey script that reads contents of a file from one site and sends it via HTTP POST method to a servlet in my GWT application. Once the content is available in my servlet I want to pass on the file content to the GWT client(i.e. trigger open the application with the file contents).
For triggering the application, I use this in my servlet code:
response.sendRedirect("/path/to/my/application");
Is there any way to read the file contents in the onModuleLoad() of my GWT entry point class? Because I am redirecting the response from servlet to the client, will the response contain the string file that was read from the other site?
Currently what I do is,
read the file from the site and send it via HTTP-POST to my server.
store the String contents in session
send a cookie to the client to indicate that a file is available in server session to be read
client on reading the cookie, sends a request to the server to get the file.
I find that this method seems to be sort of round about. Is there an easier way to do this, by accessing the file contents directly by reading the response content in client side?

You might want use load-on-startup in your web.xml file and then override the init() method in your servlet to do the required task.
<servlet>
<servlet-name>startupTasks</servlet-name>
<servlet-class>xxx.xxxxxx.server.StartupTasksServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
Additional Info can be found here

Use Timer that will continuously look into user session using GWT RPC call. If file content is found in session then just send the content to the client.
Put below code in your Entry point class.
Timer timer = new com.google.gwt.user.client.Timer() {
#Override
public void run() {
//GWT RPC call to check the user session
// if you want then cancel the timer
//timer.cancel();
}
};
timer.scheduleRepeating(5000); // 5 seconds
Or you can try this one also
If /path/to/my/application is redirecting to a JSP file then you can read session attribute in JSP file.
Server side:
session.setAttribute("keyname",fileContent);
JSP:
<div id="myHiddenDiv" style="visibility: hidden;"><%=session.getAttribute("keyname")%></div>
Entry Point:
System.out.println(getElementById("myHiddenDiv").getInnerHTML());
...
public static final native Element getElementById(String id) /*-{
return $wnd.document.getElementById(id);
}-*/;

Related

How to send file via Ajax call to Servlet

I have an HTML form in AEM where I have to attach the files and the same files will be sent to one Rest API via Java Servlet.
I am calling the Java Servlet via Ajax and able to send other String data to Java Servlet but not able to send the file Array which contains the files attached to the HTML Form attachment option while submitting the Form. How can I get the file in Java servlet?
In JS
var myFile [] is what I am sending in a ajax call.
$.ajax({
url: /servletUrl,
type: 'post',
data: {
'myFile': myFile,
},
success: function(response){
}
});
In Java :
Enum paramObject = request.getparameter();
When I put the object in HashMap and try to get the file, its type is coming as String not Object.
I am not sure where I am setting it as String.
The servlet has to be able to process Multipart-Messages.
I do not know AEM, but in Jakarta / Java Enterprise Edition / JEE / J2EE:
you have to specifically add the #Multipart annotation to the servlet.
Now, open your browser, press F12 to go into debug details, and when you trigger the request, the Network tab will display alle the infos that are posted. Look up the name of the parameter, usually it's calles file[]
When handling the request in the servlet, you can use the HttpServletRequest's request.getParts() method to find all parameter parts.
With final Part filePart = request.getPart(pFileParamName); and final InputStream filecontent = filePart.getInputStream(); you will be able to access the data.
And this will probably be very similar in most servlet frameworks.

invoke jsp from java code and get output

I have a JSP page that show data in some formatted way. the browser can call spring showInfo.do and it is forward to that JSP.
i.e.
public showInfo(HttpServletRequest request, HttpServletResponse response) {
RequestDispatcher rd = getServletContext().getRequestDispatcher("info.jsp");
dispatcher.forward(request,response);
}
The output of the JSP is html.
Now I want to save this JSP output manually from my java server side code (not in a servlet context), something like this:
void saveInfo() {
params.setParameter("info1", "data");
String responseStr = Invoke("info.jsp", params);
//save responseStr to disk
}
I want to be able to save the html page on disk from a service and make it look the same as a user can see it from a browser. So if the server is offline a user can double click on the saved html file and see in his browser the last info.
Any idea how this can be done?
Oups. The servlet specification requires the servlet container to be able to execute a JSP file. This is commonly done by converting the JSP to plain Java and the generating a servlet class file.
If you are outside of a servlet container you must:
* either fully implement a JSP execution environment, for example by using sources from a servlet container like Tomcat
* or rely on a servlet container to convert the JSP file to a .java or .class servlet and then use the Servlet interface methods on it
Alternatively, you could try to use a headless browser to capture the output of the application.

Calling a servlet from another servlet after the request dispatcher.forward method

I'm writing a web page using java servlets. When the user subscribes he will receive an email with the activation link. Currently the servlet redirects the user (using the request dispatcher) to the thank you page after it sends the email and this takes some time. I would like to redirect the user to the page before the email is created and sent and then have the email creation performed by another servlet without the user having to wait. Is this possible? How can I call a servlet from within another servlet after using the request dispatcher.forward method? Is that possible? If not, then what is the best way to do what I want? Thanks.
There are in fact 2 different problems in your question :
you want to redirect to another page
you want to continue processing after the redirection
It is simple to redirect to another URL from a servlet, just call :
response.sendRedirect("url?param=value");
For the second part, it seems that it is possible to continue processing in servlet after sending the response to the client. From my test on a Tomcat 7 servlet container, you can do so if ContentLength is set to 0 (as body is empty) and the output stream is closed. I could never have a confirmation from servlet specs, but as I wrote above it works on Tomcat :
response.sendRedirect("url?param=value");
response.setContentLength(0);
response.getOutputStream().close();
// continue after connection with client is closed
// generate and send email
To call another servlet from a servlet, you donot use request.getRequestDispatcher("xxx").forward(req,res); but rather you use response.sendRedirect("servletname or path to the servlet");
You can also add parameters to the response.SendRedirect("xxx"); so that the recieving would use that parameters to sent the email.
To add parameters to the response.sendRedirect
response.sendRedirect("<servletname>?email="+email); this will expose the user's email address with the new url.
Based on your question, you can do something like this:
request.getRequestDispatcher("page/to/display/user").forward(req,res);
session.setAttribute("email","username of user");
response.sendRedirect("servlet/to/redirect");
EDIT:
You can create a method with boolean which will redirect the user to the thank you page, when successful, then process the email:
public boolean redirect(HttpServlet request, HttpServlet){
response.sendRedirect("<servletname>");
return true;
}
In the Servlet:
if(redirect){
processEmail(parameters);
}
END EDIT
Then in the servlet that you want to send the email, you use the session to get the email that was added to the response.
String email = (String) session.getAttribute("email");
Hope this helps.
Based on your description you would like to return message to the user and then process 'in the background' email request. It shouldn't be done via other servlet. If you have Java EE server with JMS support, that is typical task for JMS and MDB. Your servlet would just put the message email sending request to the queue and returning message to the user. MDB would pick up that message and process it, and send the email.
Method with spawning is doable as you tested and should work in most of servers, however it is discouraged. See some discussion here Why spawning threads in Java EE container is discouraged?
In Java EE 7 you will have support for it via concurrency utilities - Concurrency Utilities tutorial

How to pass an InputStream from a jsp to a servlet

I have to print on a jsp page some images that i get in the form of InputStream.
First i have servlet that passes a variable containing an InputStream to a jsp page, this way:
request.setAttribute("Image", InputStream);
request.getRequestDispatcher(pagename).include(request, response);
In my jsp page i have this to get that InputStream:
${requestScope.VariableContainingInputStream}
To turn that InputStream into an image i should use a servlet this way:
<img src="ServletName">
How can i pass that InputStream to that servlet?
How can i pass that InputStream to that servlet?
You wouldn't. Your JSP would create a temporary (or permanent) file and would write the contents of the InputStream to it. You'd then provide an endpoint that would serve up the content of that file.
You would then provide the URL to that endpoint in your JSP's <img> element.
If you get it as an InputStream, I assume the image is generated dynamically or generally speaking that you have something that gives it to you depending of a number of parameters.
You should think about how a normal (or stupid ...) browser will work :
the user clicks on a link, a submit button or pass an url in adress bar
the browser generate the corresponding request and sends it to the server
the server generate a (generally HTML) page containing links to images and sends it back to browser
the browser analyzes the page, and sends separate requests for the images
the server sends back the image one for each request
the browser display full page containing images
(you could replace images by css pages, js scrips, or any other resources)
So you should not get the input stream at the time of running your jsp to compose the HTML page but write in it <image source=/ImageServlet_url?params_for_current_image/>
Then when the browser will ask for the image, the image servlet will ask for the InputStream and put it directly in response body, with the correct type in the response headers.
This is by far the most robust way of solving your problem. If really it is not an option and the InputStream is only disponible at the moment of running the jsp, you must put in in a session attribute. Then when the ImageServlet will be called, it will look for it in the session and sends it. The problem is that an InputStream in not necessarily Serializable and it is unsafe to put non serializable items in session. So you should :
set a global Hash<String, InputStream> somewhere in your app
when trying to put the InputStream in session, actually put in in the hash (with a unique key) and store the key in session
when getting the InputStream from session, get the key from the session and fetch the InputStream from the hash ... and do not forget to remove it form the hash ...
I strongly advice you to stick to the first solution, not speaking or network errors or power outages between the request of the HTML page and the image ...

Java Servlet Behaviour Question

I am currently implementing an OpenID Relying Party (RP) and Identity Provider (IdP) with Java HttpServlets using the OpenID4Java library. I have run into trouble getting two servlets to communicate with each other. I believe the problem I am having is to do more with how Servlets behave, however I have included info about my application for a better sense as to what is happening.
The scenario is as follows:
Servlet #1 (my RP) sends a request to Servlet #2 (my IdP) as follows:
httpResp.sendRedirect(authReq.getDestinationUrl(true));
Essentially authReq = a message with various OpenID specific parameters. By invoking getDestinationUrl(true) it encodes the request into a url to send via a GET.
Servlet #2 catches the above GET in its doGet method. It parses the information, and crafts a reply to send back to Servlet #1 in the following fashion:
String responseText = processRequest(httpReq, httpResp);
httpResp.setContentType("text/html");
OutputStream outputStream = httpResp.getOutputStream();
//
outputStream.write(responseText.getBytes());
outputStream.close();
My problem is, this response never makes it back to Servlet #1. I would expect that when Server #1 receives the response from Servlet #2 that its' doGet or doPost method would catch the message. However neither case happens.
Any advice would be greatly appreciated.
Thanks!
The response of 2nd servlet will directly go on client side i think because its is the original client right? Your 1st servlet is just redirecting the request.
So, if you want to communicate between servlets, Use URLConnection or Apache HttpClient to communicate with 2nd servlet.
You can also make JSP instead of 2nd servlet, then pass you data from 1st servlet to that JSP. That JSP's response will be sent to client then. After all you can do all logic in JSP what you can in servlet.
Hope this helps.
parth.
If you want two servlets to communicate with each other within an application, you can use the ServletContext object and share data via ServletContext.setAttribute and ServletContext.getAttribute and RequestDispatcher obtained via HttServletRequest or ServletContext
In your case can the Servlet#2 be invoked directly by the client? If not then you should probably refactor the processRequest(request, response) into a Utility class or a library. Which in turn can be called by both Servlet#1 and Servlete#2.
response.sendRedirect sends a redirect (301 moved permenently, ithink) to the browser. So your servlet actually sends a response to browser with 301 and then browser makes a request to servlet#2 again.
You can use RequestDispatcher to include your second servlet's response. In this way, the control returns to the first servlet after the method completes.
RequestDispatcher dispatcher = request.getRequestDispatcher(authReq.getDestinationUrl(true));
dispatcher.include(request, response);
However, with this, the response generated by the called servlet will be sent to the browser. If you want your calling servlet to capture the message from called servlet without sending to browser, you can either create a response wrapper (A wrapper writing the contents in a string) and pass this wrapper when you include the second servlet or better you can share the data in either of the scopes (Preferably 'request' scope): You can set the data in the request scope in called servlet and you can retrieve it in the calling servlet after include() completes.
When you redirect, you are telling the browser to make a new request for the URL. So there will be new request/response objects created as if you had clicked on a link in your page.
Hope this helps.

Categories