How do i call Post method of HttpServlet from GWT servlet? - java

I have two servlets, one is a GWT Servlet which extends RemoteServiceServlet and second is BasicServlet which extends HttpServlet. So my question is how do i call post method of HttpServlet from GWT Servlet. And here I confirm, I don't want to redirect to servlet using RequestDispatcher, I want to create a new Post call with new parameters.
Please guide me in right direction.
TIA!!!

Seems like an odd thing to do. Can't you put the code you want to execute in a third class/service and call it directly?
If they are on different servers (or some other reason) then you could use HttpClient (or similar)?

Related

Converting a Java program with main method into a servlet

I am new to servlets. I have a query processor java program and now, I want to use it in a Web Application. I have an interface(HTML) which generates the query and I want to run the program on a button click in the interface. For this, I want to convert the java program into a java servlet. I am working in Net Beans.
Following is the structure of my Java program :
public class ABC
{
//code
public ABC() //constructor
{
//code
}
public static void main(String[] args)
{
//code
}
}
I want to convert this into a servlet. Following is the structure of a default servlet in Net Beans.
public class Demo extends Httpservlet
{
/*----
----
----
----*/
public void processRequest(HttpServletRequest request, Httpservlet response)
throws ServletException,IOException
{
/*code*/
}
/*HttpServlet methods - doGet(), doSet() etc.*/
}
Is there any alternative for the main function in the servlet? Which method is executed first when the sevlet starts running? Can I run the Java Program on a button click on a HTML page so that I can eliminate the use of servlet?
use get or post method in servlet depend on your action. There are doGet , doPost and so many HTTP methods you need to determine in which you write code
To use your query processor on the web you will have to build a Java Web Application.
Try the tutorial below and then call your ABC class from a Servlet.
Introduction to Developing Web Applications
Create a Dynamic web project, add new servlet usee doGet method or doPost method refer this link for the same.
servlet example
Hope this helps.
Please have in mind that the purpose of use is different in those two cases. While the main method of a class is invoked when you compile and run it as part of an application (run on a machine), the doGet and doPost methods are invoked in a servlet after a GET/POST request is made by client side to the server side, on which the Servlet lives.
On the first case, usually everything occurs on a specified machine, following the logic "do something, then done", and on the second case, you have a Request/Response Model between Clients and a Server (following the logic "do something when asked, then wait for being asked again"). You need to have a Server (e.g. Tomcat) set up to use the servlets.

Access GWT POST parameters via servlet?

I'm creating a GWT application that will be accessed by a POST request, which contains parameters I care about (user id, etc.).
All the reading I've done so far has led me to believe that I should create a servlet (I'm using tomcat) that will handle the POST parameters and then forward to my GWT application. I've gotten this working, but I'm still having trouble passing this data to my application. I've seen 3 suggested approaches:
Save data to context: I have this working right now, but I'm not happy with it. When the servlet is accessed, I parse the parameters and update the context of my GWT web application and then forward to the application where I make an RPC call to read the context. This does what I want it to, but this creates a race condition when multiple users try to access the application at the same and the context is rapidly changing.
Store data in session: I've tried saving the data to the request session in my servlet, and then accessing the session in my RPC, but I always get a new/different session, so I assume I'm mucking this up somewhere.
Save session on servlet
HttpSession session = request.getSession();
session.setAttribute("test", "testValue");
response.sendRedirect(response.encodeRedirectURL("/GWT_Application"));
Access session in RPC
HttpSession session = this.getThreadLocalRequest().getSession();
session.getAttribute("test");
This returns a different session, which results in the "test" attribute being null.
Pass data in URL: My application will be opened in an iframe, meaning Window.location.getParameter() will not be usable.
Any help would be greatly appreciated! I'm still learning GWT and web development in general so don't be afraid to call me out on any obvious or silly mistakes.
Thanks!
SOLUTION
I figured out what the issue was with my session approach: the servlet in which I was previously trying to save the session data was in a separate tomcat web app from my GWT application. Moving them to the same web app solved my problems and it now works. I'm not sure, but I'm guessing that this was a problem because redirecting to another web app switches the context. I'll outline my whole approach in the hopes this saves someone else some time later:
Put your servlet code in the server folder of your GWT project:
package GWTApplication.server;
public class myServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
session.setAttribute("myAttribute", request.getParameter("myParam");
// handle rest of POST parameters
response.sendRedirect(response.encodeRedirectURL("/GWTApplication");
}
}
Map servlet in your GWT application's web.xml:
<servlet>
<servlet-name>myServlet</servlet-name>
<servlet-class>GWTApplication.myServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myServlet</servlet-name>
<url-pattern>/myServlet</url-pattern>
</servlet-mapping>
This servlet should now be accessible at .../GWTApplication/myServlet
Next make a standar RPC. Within whatever method you will be calling in the ServiceImpl class on the server:
HttpSession session = this.getThreadLocalRequest().getSession();
return session.getAttribute("myAttribute");
Finally, make your RPC call in the onModuleLoad() method of you GWT application. As a recap:
Send the original POST request to the servlet
Save POST parameters to session variables
Redirect to GWT application
Make RPC call in onModuleLoad()
Read session variables in ServiceImpl class
You can talk with servlets through RPC call in GWT
You need to make a RPC call in the starting point of GWT application.
Set that data to serverside session and get the session data in servceImpl call of GWT which extends to RemoteServiceServlet.
Example :
YourServiceImpl extends RemoteServiceServlet {
#ovveride
doGet(){
//you can access session here
}
#ovveride
doPost(){
//you can access session here
}
#ovveride
doPut(){
//you can access session here
}
----your other methods
}
A brief Example I wrote here:How to make an GWT server call(GWT RPC?)
Since RemoteServiceServlet extends HttpServlet, you can just override doPost() method to access your POST requests. Don't forget to call super.doPost() EDIT: This doesn't work because the method is finalized in AbstractRemoteServiceServlet so it cannot be overridden.
Also, GWT Servlets POST data using the proprietary GWT RPC format. Read more about that format and how to interpret it here: GWT RPC data format
EDIT
There are several methods you can override in your ServiceImpl class that extends RemoteServiceServlet:
public String processCall(String payload) will give you a String representation of the incoming request.
protected void onAfterRequestDeserialized(RPCRequest rpcRequest) will give you a RPCRequest object that has an array of parameters, along with the method that was called.
public void service(ServletRequest request, ServletResponse response) will give you all the Attributes of the HTTP request.

Why doGet(), doPost() Methods are "protected"?

I'm confused about the access modifier of the doGet(), doPost() and other methods of HttpServlet class.
Why are they protected?
As per my understanding, the protected modifier of doGet() means that a client has to be in the same package (or a child - through inheritance) to access doGet(). So how will the invoking JSP or the container access it?
They're protected primarily for two reasons.
So that external classes can't just call them, like you reasoned. Technically, there are ways to get around method visibility modifiers using Java Reflection (if the Security Manager allows it or there is none), but ordinarily, a protected method can only be accessed by classes in the same package or by subclasses, which brings me to point #2.
So that subclasses or concrete implementations of HttpServlet can override them. Well, they can also be overridden if they were public, but see point #1.
Now your other question, "So how will the invoking JSP or the Container access it?"
HttpServlet implements the Servlet interface, which declares a service(ServletRequest, ServletResponse) method. This, of course, by default becomes public in HttpServlet. This is the primary entry point (for containers) to call into HttpServlet implementations.
My guess (I haven't dived into the source) is that the default implementation of HttpServlet checks the ServletRequest object passed in, which is actually an HttpServletRequest and which defines a getMethod() method that returns the HTTP method used. It then dispatches to either doGet() or doPost() depending on the HTTP request method.
Here's from the official javadoc.
Provides an abstract class to be subclassed to create an HTTP servlet suitable for a Web site. A subclass of HttpServlet must override at least one method, usually one of these:
doGet, if the servlet supports HTTP GET requests
doPost, for HTTP POST requests
doPut, for HTTP PUT requests
doDelete, for HTTP DELETE requests
init and destroy, to manage resources that are held for the life of the servlet
getServletInfo, which the servlet uses to provide information about itself
And also
There's almost no reason to override the service method. service handles standard HTTP requests by dispatching them to the handler methods for each HTTP request type (the doXXX methods listed above).
And in the docs for doGet method:
Called by the server (via the service method) to allow a servlet to handle a GET request.
So HttpServlet is designed for inheritance and the entry point is the service method. Hence doGet is protected to enforce clear API.
doGet and doPost are the basic methods in generating and sending the HttpResponse to the client (i.e usually Browser or HttpClient)
Also, The container calls the Servlet.service() method which is public. It then calls the HttpServlet.service() method which is protected and it then call doGet()/doPost() method.
Suppose I am having a class MyClass which is not a servlet, then do I want my class to have methods doGet and doPost? Well if it's not a servlet then how can it respond or capture any web based requests.
Only servlets can capture and respond to web based requets.
So it makes sense that I will be able to capture and respond to web based requests only if my class extends Servlet and and hence I will be able to use doGet, doPost and variuos other methods.
I think you are wondering about how the servlet container calls the protected method doGet and doPost.
Actually there is an interface named javax.servlet.Servlet. A class named GenericServlet implement the interface. And the HTTPServlet class extends this GenericServlet.
When there is an http request to an HTTPServlet, the container simply use the method service(...) declared in the interface. That method is public. Then in the GenericServlet, the service method called doGet and doPost. If your servlet class extends the HTTPServlet class and override the doPost method, then this method will finally get called.
Think of protected as an invitation to override a method. You are deriving a class from HttpServlet so these methods are the ones to override. They all have a default action so you can just override the methods which are of interest to your application.

How to send to a jsp page from a rest call

I've written a rest interface (with jersey), a browser will be calling this rest interface. I would like show some html/jsp to the user as a response to this rest call...
Is this possible? How do I do it?
Yes, that is possible. This post as well as this one gives a hint how to use Viewables to return JSPs as a response.

The indestructibles - HTTP Parameters

I always wondered why there exists no removeParameters() method in Servlet API.
What could be the motive behind this design?
Here is a scenario: I am posed with a challenge in a proprietary MVC framework that I am compelled to use. This framework uses a Controller Servlet that hosts an algorithm in it's post method:
doPost() {
//create instance of action - just like struts action
action.init
action.preexecution
if(redirection state is not set)
action.process
action.postprocess
action.finish
}
The only way I can skip process of any particular action would be by setting a redirection url. The Controller Servlet is FINAL. Now, when I do a requestdispatcher.forward from say the preexecution method of an action, the controller will go ahead and execute the rest of the methods and not skip the rest. I cannot change this behavior, neither can I set the redirect, coz I need to do a forward. It works fine as long as I am not forwarding request to the same action. When a request is forwarded to the same action, the http parameters are all the same. This would take it into a never ending loop. Hence, I am compelled to add extra parameters indicating that it is a repeat request and should be treated differently.
Not sure if my problem made sense, but thought this is a good forum to post the same.
Umm... because it would serve no purpose? Request parameters are sent by the client to the server. The server is free to ignore them, but what practical effect would you expect such a removeParameter() method to have?
Edit: Request parameters are meant for the communication between server and client. For server-internal communication, you can use request attributes, which can be set and removed.
EDIT: McDowell reminded me of HttpServletRequestWrapper, so I'm changing the below to make it a little less work... Thanks McD!
You can decorate the request to "hide" parameters you don't want and/or add extra parameters.
Something like (off the top of me head -- no compiling so the API might be a tweak off...)
public class MyParameterHider extends HttpServletRequestWrapper {
public MyParameterHider(HttpServletRequest request) {
super(request);
}
public String getParameter(String name) {
if ("parameterToHide".equals(name))
return null;
return realRequest.getParameter(name);
}
// similar for getParameterNames and getParameterMap - don't include the hidden parm
// all other methods are strictly pass-through and are automatically
// handled by HttpServletRequestWrapper
}
In your forward, just wrap the request in a ParameterHider when calling doFilter:
dispatcher.forward(new MyParameterHider(request), response);
Patterns FTW!
Hope this helps!

Categories

Resources