The getRequestDispatcher() method of ServletRequest interface returns the object of RequestDispatcher.
I know that getRequestDispatcher() method is in the Interface ServletRequest. As it is an interface, it won't define the method.
Furthermore, this interface is again inherited in another interface HttpServletRequest. But being an interface, it won't define its methods.
Now, after carefully checking the JavaDocs, I could not find any class that implemented either of these two interfaces, and defined the getRequestDispatcher() method.
So I was wondering where did they define this method
Thanks in advance.
The class which implements is org.apache.catalina.connector.RequestFacade , in case of TOMCAT container.
The implementation is basically dependent on containers & every container has its own implementation adhering to the J2EE Specs.
Use the below code to check the implementation class :-
public class TestServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
throws ServletException, IOException {
System.out.println(httpServletRequest.getClass());
}
}
Output :- org.apache.catalina.connector.RequestFacade
You can see this class Offical Doc here, and can check that it has implemented the interface javax.servlet.ServletRequest and its methods like getRequestDispatcher() etc.
Each container (Tomcat, Jetty, etc.) has its own class that implements HttpServletRequest. This class implements all the methods of the interface. An instance of this class is passed by the container to your servlet.
If you're really curious about it, add
System.out.println(request.getClass());
to your servlet, and you'll know the name of the concrete class.
But really, you don't need to know about it. All you need to know is that it implements the HttpServletRequest interface and thus fulfills the contract described in the javadoc and the specifications.
For jetty v6 it is org.mortbay.jetty.servlet.ServletHandler and its return org.mortbay.jetty.servlet.Dispatcher instance.
And this is how forward from Dispatcher works there:
It took original request, replace request url with new value
Clear output stream.
Execute request-responce pair via context.handle(request, responce)
Reset original value of request url for request.
Related
I'm studying servlets and I was looking at a fully working example created by my professor. The service() method of my servlet looks like this:
public void service (ServletRequest req, ServletResponse res)
throws ServletException, IOException {
res.setContentType( "text/plain");
PrintWriter out = res.getWriter();
out.println( "Some response" );
out.close();
}
In the above example service() uses a ServletResponse object, so I went into my servlet-api .jar, searched for javax.servlet.ServletResponse.class and found out that ServletResponse.class is an interface (public abstract interface javax.servlet.ServletResponse) . So in my code I use an object of type ServletResponse which is an interface, but I thought that you could not instantiate an interface in Java. I also noticed that this interface is implemented by ServletResponseWrapper.class.
So my questions are:
Why does compiler let me instantiate an interface?
why don't we use a ServletResponseWrapper object?
You aren't instantiating the interface ServletResponse. You are using a reference that was passed to you by the servlet container when it calls the service() method on your servlet. The container instantiates a class that implements ServletRepsonse interface. The instantiated (concrete) class could be ServletResponseWrapper or any other "internal" classes as long as it implements the ServletResponse interface.
Try printing res.getClass().getName() in your service() method. It should tell you the exact class name that's being instantiated by the servlet container.
I don't believe you did instantiate a ServletResponse; you're simply using an instance that was passed to you. You don't care about the implementation details; you just care about the contract specified by the interface.
An interface specified the contact and there could be a variety of implementations for it. They could each implement the contract in different ways but they behavior of each would be exactly the same (matching what is specified in the interface).
I read the servlet-3.0 specification and have got one question about the ServletRequest object. Currenctly I have a filter chain
public class MyFilter implements Filter{
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
//do filter
}
}
after doing filters the javax.servlet.Servlet's
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException;
comes into play. Is it reliable that both in the filter's method and the service method operate on the same object reference? The servlet specification said this:
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 startA sync method is invoked on the request object
But it;s not obvious to me that the ServletRequest object is a singleton per one request handling.
Upd: To be more specific, I need to return the HttpSession instance within Filter's doFilter method and Servlet's do_HttpMethod_ method. Is it always the same? I mean httpServletRequest.getSession()
A container uses a single request object for a given request. However any filter can wrapper the request object so your filter or servlet may be getting a wrapper depending on what other filters do. Usually as an app developer you would know if this is the case. If no wrappers are used the filter and servlets get the same request object.
For info on request wrappers see:
http://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServletRequestWrapper.html
So when you call getSession() you may get the container implementation of the method or that provided by a wrapper. However note that an HttpServletRequestWrapper object provides a getRequest() method which returns the request object it wraps so you can recurse through wrappers until you get the original and then call it. Lots of examples how to do this on the web.
ServletRequest is an interface and the same is used in doFilter method as well as service method. So both are going to return the same session object (if you call getSession()).
Servlet as well as Filter uses same interface so it's going to behave same way. I am not sure why you are curious to know if it's singleton ? May be you can check servlet specification to know more about it.
I have been studying spring and spring mvc framework, and I am curious to know that how the spring container gives us the reference to whatever Interface or Class type we pass as an argument to our methods.
For instance, when we create a Servlet in a web application it extends HttpServlet so when we override the doGet or doPost method the web container instantiates the servlet and pass a reference to HttpServletRequest and HttpServletResponse objects to doGet or doPost methods as:
public class DemoServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//container gives reference to request and response object
}
}
The question that comes to my mind is how the spring container knows what object reference it need to instantiate i.e how does it scans the methods as our class does not override any Class or Interface method so that it can know that it needs to provide the reference to that object. As these class or interface types are not declared as beans in application context file. For instance:
#Controller
#RequestMapping("/")
public class ContactController {
#RequestMapping(value="savecontact", method=RequestMethod.POST)
public String saveContact(#ModelAttribute("contact") Contact contact, BindingResult errors, HttpServletRequest request, HttpServletResponse response) {
...
}
}
How does Spring provide reference to BindingResult, HttpServletRequest, HttpServletResponse objects and any other Spring or Servlet class or interface type that we pass to method as arguments? Does it have a list of default objects that it instantiates on the application start up or does it scans the methods?
When you annotate a controller method with the #RequestMapping, the parameters of the method will be a subject of the argument resolving process. An interface HandlerMethodArgumentResolver and its implementations are at the core of this mechanism. The interface holds two methods supports, and resolveArguments
In simple terms, all listed arguments are passed through a list of the default resolvers registered with RequestMappingHandlerAdapter (check the getDefaultArgumentResolvers method), if the resolver supports the type, a resolveArgument method is called and an instance is injected as an argument.
For the four types you've declared, the respective resolvers are
ServletModelAttributeMethodProcessor
ErrorsMethodArgumentResolver
ServletRequestMethodArgumentResolver
ServletResponseMethodArgumentResolver
all registered by default
Based on argument resolving mechanism, its also quite easy to add a custom resolver, that will instantiate and inject any custom type as well
As a follow-on to Master Slave's answer...about #ModelAttribute arguments
An #ModelAttribute on a method argument indicates the argument should be retrieved from the model. If not present in the model,
the argument should be instantiated first and then added to the model.
Once present in the model, the argument’s fields should be
populated from all request parameters that have matching names. This
is known as data binding in Spring MVC
"where" does spring find a #ModelAttribute method arg:
It may already be in the model
due to use of #SessionAttributes
due to an #ModelAttribute method in the same controller
It may be retrieved based on a URI template variable and type converter (explained in more detail below).
It may be instantiated using its default constructor.
I have a single-instance class, implementing ExceptionMapper. It's not a static class, but it's a class for which I know only single instance is created (I checked - constructor is called only once).
My class uses #Context HttpServletRequest, and I can clearly observe that when my ExceptionMapper.toResponse() method is called, the #Context 'request' parameter has a value which is relevant for a request where the exception is thrown.
The doc says this is indeed by-design supported feature and that it's done by using "proxies".
I wonder how exactly this is implemented - how a single instance can have different member variable values simultaneously?
Thank you,
AG
P.S.: here's the test code:
#Provider
public class MyExceptionMapper implements ExceptionMapper<Exception> {
public MyExceptionMapper() {
System.out.println("CTOR!!");
}
#Context HttpServletRequest req;
public static boolean done = false;
public Response toResponse(Exception ex) {
if (!done) {
done = true;
Thread.sleep(10000);
}
System.out.println(req.getRequestURI());
return null;
}
}
My REST handler method throws exception, so when I execute the following 2 requests "in parallel" (the sleep above makes sure first one is not finished when second one arrives and IMHO should modify the one-and-only 'req' field):
- http://localhost/app/one
- http://localhost/app/two
my program prints:
CTOR!
http://localhost/app/one
http://localhost/app/two
The simplest method of achieving the effect you observe is for the injected HttpServletRequest object to actually be a proxy object, a thread-aware delegate for the real HttpServletRequest. When you call methods on the delegate, all they do is look up the correct real object (e.g., via a thread local variable) and pass the call onto that. This strategy is relatively simple to get right, and as it is an interface we definitely don't have to worry about field accesses (which are quite a bit trickier to proxy for).
There's a few different ways to construct such a proxy object. In particular, it could be done by directly implementing the HttpServletRequest interface, or it could be done more generically via the Java general dynamic proxy mechanism (which can construct a proxy for any interface). There are other more elaborate possibilities such as runtime code generation, but they're unnecessary here. OTOH, I wouldn't be at all surprised if HttpServletRequest was directly implemented; it's a somewhat important class for a JAX-RS implementation…
I have just started spring, I found that somewhere we are using handlerequest() method in controller and somewhere we are using handlerequestinternal() method.
I have tried google-ing this, but did not find any specific point.
Can any one explain what is the difference between these two functions and when we should implement each of them?
As I know spring framework will call by default handlerequest() function, so we can put our service layer there itself.
I am sure handlerequestinternal() must be providing some extra feature, but not sure.
Please help me to understand this.
Both handleRequest and handleRequestInternal are used by the old Spring 2.0 controller framework.
handleRequestInternal is used when you're extending one of the pre-supplied base support classes (e.g. AbstractController, SimpleFormController, etc). These use the Template design pattern, and you supply your business logic in that method.
handleRequest is the method specified on the Controller interface itself. If you directly implement that interface, rather than extending one of the above base classes, then you need to implement handleRequest directly.
Both are obsolete, and not used in controllers written for Spring 2.5 and later.
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
this.checkAndPrepare(request, response, this instanceof LastModified);
if (this.synchronizeOnSession) {
HttpSession session = request.getSession(false);
if (session != null) {
Object mutex = WebUtils.getSessionMutex(session);
synchronized(mutex) {
return this.handleRequestInternal(request, response);
}
}
}
return this.handleRequestInternal(request, response);
}
protected abstract ModelAndView handleRequestInternal(HttpServletRequest var1, HttpServletResponse var2) throws Exception;
}
if in controller template classes like AbstractController and ParameterizableViewConterollers in this it will the child classes of Controller interface so spring peoples internally override the handleRequest method and call the abstract handleRequestInternal method so whenever we are using template classes we use this method otherwise we use the handleRequest() method only this the difference i think!.