I'm new to Java server-side programming, my question is basically to get to a starting point using Servlets (low level without using spring mvc etc.) and then build my way up from there, coming from node.js background where a route definition would start with a function (app.get(request, response) {}, app.post(request, response) {} etc.), and the function would receive request and response in parameters for one of http methods (GET, POST, PUT, DELETE).
If someone can please help on the starting point of how do I define methods against a route (let's say /users) inside a servlet class that'd map to http methods while providing request and response in it's parameters.
My attempt
public class FirstServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException , IOException {
}
I believe what you want are Servlet mappings. You can also find a bit more info here
But basically this is the way you tell the webserver (e.g. Tomcat) what servlet to use to answer requests sent to a given url pattern. Thus you map the pattern with the servlet you want to use to serve it.
You can also find more info on the inner workings here.
Edit: If you want to handle all verbs you can use a service. From the first link:
You may have seen other servlet examples implement the doPost() and/or doGet() methods. These methods reply only to POST or GET requests; if you want to handle all request types from a single method, your servlet can simply implement the service() method. (However, if you choose to implement the service() method, you cannot implement the doPost() or doGet() methods, unless you call super.service() at the beginning of the service() method.) The HTTP servlet specification describes other methods used to handle other request types, but all of these methods are collectively referred to as service methods.
All the service methods take the same parameter arguments. An
HttpServletRequest provides information about the request, and your
servlet uses an HttpServletResponse to reply to the HTTP client. The
service method looks like the following:
public void service(HttpServletRequest req,
HttpServletResponse res) throws IOException { ... }
Related
I am trying to make an API with Jetty Server, and I have this simple GET request:
#GET
public String helloWorld(){
return "Hello world";
}
In order to make a POST request, I assume that one must save the input to the Jetty server. I have tried to research for quite a while, but found nothing.
I imagine something like this:
#POST
public void Save(String stringToSave) {
// Save to DB?
}
You could likely google this but let me give you a quick overview. A Servlet is a chunk of code that is normally run during an HTTP action - GET, POST, etc. It is the original technology of the JavaEE world, having been released in the late 1990's.
A simple Java servlet, using modern annotations, would look something like:
#WebServlet(name = "SampleServlet", urlPatterns = "/sampleServlet")
public class SampleServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// called when an HTTP POST is sent
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// called when an HTTP GET is sent
}
}
The important parts to note are that the class extends HttpServlet and that you have to write code to pull data out of the request and push it into the response. This isn't bad to do but it does have to be done.
JAX-RS is a newer standard, aimed simplifying the creation of REST services. It too is a chunk of code that runs during an HTTP interaction.
A simple example of this would be:
#Path("/sampleService")
public class SampleService{
#Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
#Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
#POST
#Path("/v1/hello")
public Response sayHello( SomeObject someobject ) {
The code here is both simpler and a bit more complex. The use of annotations helps determine the path that the service exists on a URL (in this case /sampleService/v1/hello), the HTTP method, and the Content-Type for both the request and response. Additionally, if the SomeObject object is defined correctly, the JAX-RS framework will automatically deserialize the incoming JSON or XML payload into an object for you.
The Response object contains the HTTP response code (perhaps a teapot) and a response body. In this example, the body will be automatically serialized back to the requestor in a way that matches the Accept header of the HTTP request (i.e., JSON for an application/json Accept header and XML for application/xml).
Note that while not directly related the JAX-RS framework takes advantage of the Servlet framework. Indeed in JAX-RS you can access the HttpServletRequest and HttpServletResponse object in your methods.
Which way is "better"? In general I would recommend using JAX-RS where possible as it is the newer standard and is a bit easier to implement. However, if you do any work in the JavaEE world you're very likely to run into Servlet code so it's important to understand it too.
Note that both Servlets and JAX-RS require an application server of some sort. Jetty is one of those. Another very common one is Tomcat. The application server sets up the environment for your code and listens for incoming HTTP messages. When it gets one it looks to see if it knows how to handle the URL and routes to the appropriate place. In the servlet world the server routes solely on the URL. In the JAX-RS world the server routes on the URL and, if specified by the #Consumes annotation, the HTTP Content-Type header too.
There is much more but let's start there and see if it answers what you're after.
How does the Tomcat container calls service(ServletRequest req, ServletResponse res) method?
Where can I look for implementation of this call?
How can I see how this req and res objects (that passed to service() method) are created?
Although the Tomcat Architecture page is in TODO status, there is at least a link to the UML sequence diagram of the request processing. Combining with Tomcat's source code, it is a good starting point.
If you want to know it, first clone apache tomcat source code
git clone https://github.com/apache/tomcat.git
Then inside the cloned repository, launch this command to search where it is invoked service method:
grep -H -n -r "\.service(" --include=*.java
You will find a short file list:
java/javax/servlet/jsp/PageContext.java:107: * in this PageContext until the return from the current Servlet.service()
java/org/apache/catalina/connector/Request.java:3128: // that set towards the start of CoyoyeAdapter.service()
java/org/apache/catalina/core/ApplicationFilterChain.java:231: servlet.service(request, response);
java/org/apache/catalina/servlets/DefaultServlet.java:411: super.service(req, resp);
java/org/apache/catalina/servlets/WebdavServlet.java:349: super.service(req, resp);
java/org/apache/coyote/ajp/AjpProcessor.java:403: getAdapter().service(request, response);
java/org/apache/coyote/AsyncStateMachine.java:41: * been called during a single Servlet.service() method. The
java/org/apache/coyote/AsyncStateMachine.java:58: * been called during a single Servlet.service() method. The
java/org/apache/coyote/http11/Http11Processor.java:498: getAdapter().service(request, response);
java/org/apache/coyote/http2/StreamProcessor.java:257: adapter.service(request, response);
java/org/apache/jasper/Constants.java:41: * HttpJspBase.service(). This is where most of the code generated
java/org/apache/jasper/servlet/JspServlet.java:385: wrapper.service(request, response, precompile);
java/org/apache/jasper/servlet/JspServletWrapper.java:440: servlet.service(request, response);
java/org/apache/jasper/servlet/JspServletWrapper.java:443: servlet.service(request, response);
The most intresting one is java/org/apache/catalina/core/ApplicationFilterChain.java. You wil find more coincidences, but much of them are because there is another interface into Tomcat source code that has a very similar method java/org/apache/coyote/Adapter.java ignore it.
Once you get java/org/apache/catalina/core/ApplicationFilterChain.java, you can edit, got to line 231 and see where the service method is called.
However, both req and res objects are not created in that place. Finding how those are created seems to be a bit more complex and requires more time.
Servlet lifecycle is controlled by the underlying container. Once the servlet has been initialized and there is a request, Tomcat will call the servlet's service method to process the request.
Service method will delegate request to your Servlet class where you can get access to req and res objects in doGet or doPost methods.
public void doGet(HttpServletRequest req, HttpServletResponse res){
}
Update :
1. Upon request from the client, Container creates two objects : HttpServletRequest and HttpServletResponse.
2. Based on the request, Container will find correct Servlet (as per URL mapping), creates new thread for that particular request(one-to-one mapping - new thread for each request) and calls Servlet's service method, passing in created HttpServletRequest and HttpServletResponse objects as arguments.
3. Based on request method (GET or POST) service() method will call doGet() or doPost() method in Servlet, again passing the same HttpServletRequest and HttpServletResponse objects as arguments.
Those are Servlet specifications in a nutshell. How does Tomcat act exactly is implementation specific, it is not controlled by specification. If you need to know how exactly it is implemented in Tomcat, you might check it's source code.
This question already has answers here:
How doGet() or doPost method invokes service() method internally
(3 answers)
Closed 6 years ago.
How does the servlet container know whether to call doGet or doPost method.
When I make a get request doGet is called, When I make a post request doPost is called , but where is the logic to decide this .
You never really call doGet() or doPost() (the service() method will, and it is called by the Web container as you read in the lifecycle).
The service() method detects the HTTP method used and delegates to doGet(), doPost() and other methods which process HTTP requests in a HTTPServlet. It also encapsulates the ServletRequest and ServletResponse objects in HttpServletRequest and HttpServletResponse objects which contain additional context data from the HTTP headers.
Tahnks to #helderdarocha.
For more;
The logic is in the HTTP protocol and its management by the servlet container (Tomcat, Glassfish, Jetty, ...)
The first word of the request (at the TCP level) is the HTTP verb, generally GET or POST but it can be DELETE, PUT, OPTIONS, HEAD, TRACE,...
The servlet container call the service method of the servlet, but the default implementation of HttpServlet.service method contains the logic to dispatch to the proper method. Extract from the Javadoc :
public void service(ServletRequest req,
ServletResponse res)
throws ServletException,
java.io.IOException
Dispatches client requests to the protected service method. There's no need to override this method.
protected void service(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException,
java.io.IOException
Receives standard HTTP requests from the public service method and dispatches them to the doXXX methods defined in this class. This method is an HTTP-specific version of the Servlet.service(javax.servlet.ServletRequest, javax.servlet.ServletResponse) method. There's no need to override this method.
javax.servlet.http.HttpServlet.service(HttpServletRequest req, HttpServletResponse resp) contains the logic for that.
Request Method is a standard HTTP/1.1 token, which is sent as part of request headers
Please refer to:-
http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html
I thought, that we cannot override service() method in any specific servlet. So what is purpose of httpservlet service method?
From **service method ()** only your actual method (get,post ...etc) decides to call.
The default service() method in an HTTP servlet routes the request to another method based on the HTTP transfer method (POST, and GET). For example, HTTP POST requests are routed to the doPost() method, HTTP GET requests are routed to the doGet() method. This routing enables the servlet to perform different request data processing depending on the transfer method. Because the routing takes place in service(), you do not need to override service() in an HTTP servlet. Instead, override doGet(), anddoPost() depending on the expected request type.
The servlet service() method that perform the task of determining the method that has been called i.e. get/post/trace/head/options/put/delete. These are the 'big seven' methods since they are the most commonly used ones.
After determining the method which is actually called,it then delegates the task to the correspondin method.
You can either use,
public void doGet(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponseresponse)
throws javax.servlet.ServletException,java.io.IOException {...}
or,
public void doPost(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponseresponse)
throws javax.servlet.ServletException,java.io.IOException {...}
instead of,
public void service(javax.servlet.ServletRequest request,
javax.servlet.ServletResponseresponse)
throws javax.servlet.ServletException,java.io.IOException {...}
I wonder how cn i pass a request parameter of a servlet as a parameter to another java file of my web app that doesm't have POST and GET methods?
Thanks in advance
Antonis
Simply by getting the request parameter from the HttpServletRequest object, and using it as a parameter.
void doGet(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException,
java.io.IOException {
String param = req.getParameter("name_of_your_param");
new YourOtherClass().yourOtherMethod(param);
//implement the rest to return a response
}
I'm excluding obvious things like input validation on the parameter (e.g. if the http client didn't send the parameter in the request, the result of getParameter is null) and sending the response.
Please takes some time to become familiar with the Servlet API and refer to it whenever you are curious how to do something with your Servlets and Request/Response objects: http://download.oracle.com/docs/cd/E17802_01/products/products/servlet/2.5/docs/servlet-2_5-mr2/index.html
What's the problem with someObject.someMethod(request, response) ?
Your request always passes through a Servlet, so:
extract the needed parameters there
pass them as arguments to the helper
There is another option - to store what you need in a ThreadLocal variable, because each request is handled in a separate thread, but that's to be avoided.