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 {...}
Related
I have a spring boot application with SOAP endpoints and an interceptor class which implements EndpointInterceptor.The problem is, there is no overridden methods available in this interface which have access to HttpServletRequest and HttpServletResponse.
My question is :
How can I get HttpServletRequest and HttpServletResponse objects whenever an API request comes using a SOAP interceptor (I saw many examples which is using WebMvcConfigurerAdapter and HandlerInterceptor but it is working only for Rest #Controller. In my case it is SOAP with #Endpoint and it is not calling the overridden methods).
If that is not possible , how can i get make this object from MessageContext since the handleRequest overridden method is having that parameter as show below
#Override
public boolean handleRequest(MessageContext messageContext,
Object endpoint) throws Exception {
LOG.info("Endpoint Request Handling");
return true;
}
Spring-ws has TransportContext class for storing the current underlying connection. You can access it via TransportContextHolder class statically in the code.
If you are sure that the underlying connection is a HttpServletConnection then you could do something like this inside the interceptor methods:
TransportContext ctx = TransportContextHolder.getTransportContext();
HttpServletRequest req = ((HttpServletConnection) ctx.getConnection()).getHttpServletRequest();
If you want to manipulate (Override) the HttpServletRequest and HttpServletResponse
before/after reaching the endpoints using Interceptors would be a bad idea as the requests reached at that level would be preprocessed and would not give you the option of modification.
You could use Filters instead of Interceptors to achieve what your trying to do.
I make an ajax call and hit the following code in java class
if("callfirstPageStoredProcedure".equalsIgnoreCase(request.getParameter("mode"))) {
synchronized(this) {
pb = new PayrollBean(request, response, logininfo, request.getParameter("mode"));
pb.startThread();
}
}
so In class payrollBean with the help of this new constructor I set requet and response arguments as Global variables.
Then in run() method I try to access those Parameters but it seems they are not available here and nullPointerexception is thrown.
Constructor :
public PayrollBean(HttpServletRequest request, HttpServletResponse response, LoginInfo loginInfo, String methodToCall){
this.request = request;
this.response = response;
this.loginInfo = loginInfo;
this.methodToCall = methodToCall;
}
Start method Calling :
public void startThread(){
payrollThread=new Thread(this);
payrollThread.start();
System.err.println("The payrollThread is started Now!!!!!!!!!!!!!!!!!!!");
}
Run method:
public void run(){
int InCatch = 0;
try {
if("callfirstPageStoredProcedure".equalsIgnoreCase(methodToCall)) {
callfirstPageStoredProcedure(request, response, loginInfo);
}
}
Any get any idea what am I be doing wrong here?
Each request object is valid only within the scope of a servlet’s
service method, or within the scope of a filter’s doFilter method
Therefore, you shouldn't save any reference to HttpServletRequest and HttpServletResponse for use in another thread. You can not access request parameters once the original request has finished. And your Thread sometimes will be executed before the request has finished and sometimes later.
Instead you should copy the information you need from the original request for later processing.
Extract from Java Servlet Specification:
3.11 Lifetime of the Request Object
Each request object is valid only within the scope of a servlet’s service method, or within the scope of a filter’s doFilter method,
unless the asynchronous processing is enabled for the component and
the startAsync method is invoked on the request object. In the case
where asynchronous processing occurs, the request object remains valid
until complete is invoked on the AsyncContext. Containers commonly
recycle request objects in order to avoid the performance overhead of
request object creation. The developer must be aware that
maintaining references to request objects for which startAsync has not
been called outside the scope described above is not recommended as it
may have indeterminate results.
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 { ... }
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 need to forward my request (to a jsp but I don't think it's matter) from an http.Filter
if the URI of the original request pass some validation that my filter runs.
I found this page that faced similar task
Still I need to figure the following:
How can I get ServletContext in doFilter() method (in order to call forward API) getServletContext() is not recignized
Do I have to call chain.doFilter() before the forward, after the forward or not at all?
In addition do I have to call chain.doFilter() if my validation passed or only if it fails (because in this case I won't continue to forward my page)?
This question actually continue this thread,
to be more obvious, the code could be something like:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if (request instanceof HttpServletRequest) {
HttpServletRequest httpServletRequest = ((HttpServletRequest)request);
String requestURI = httpServletRequest.getRequestURI();
String contextPath = httpServletRequest.getContextPath();
if (<this is my implementation of the validation of this filter>){
getServletContext().getRequestDispatcher(
"MySpecific.jsp").forward(request,response);
}
}
chain.doFilter(request,response);
}
How can I get ServletContext in doFilter() method?
httpServletRequest.getSession().getServletContext();
Do I have to call chain.doFilter() before the forward, after the forward or not at all? In addition do I have to call chain.doFilter() if my validation passed or only if it fails (because in this case I won't continue to forward my page)?
I would say that if you forwarded the request, you should not call chain.doFilter() - the forwarded request will get filtered according to its own filter configuration. If your validation failed though, it depends on what the semantics of your web app are - if the original page is some sort of general error/login/welcome screen, you may want to continue to that when the validation failed. It is hard to say without knowing more of the context.
To get the ServletContext, you've got 2 options:
Store off the FilterConfig during the initialization and call FilterConfig.getServletContext()
call HttpServletRequest.getSession().getServletContext()
I don't think you necessarily need the ServletContext to get the RequestDispatcher as you could just call HttpServletRequest.getRequestDispatcher().
In relation to FilterChain.doFilter() call, if you're forwarding, I would think you wouldn't make the call, as once you forward, I assume you don't want any of the standard behavior to take place.
If you don't forward (you don't fall into your if block), then I'd call the FilterChain.doFilter() method, however that assumes there is a target on the other end to be invoked.