Java interfaces in jar archives - java

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).

Related

Understanding request object in servlet-api. Is it a singleton?

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.

Which class provides the implementation for getRequestDispatcher() method

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.

How does Spring container gives reference to interface or class type we pass as an arguments to method

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.

Difference between handleRequestInternal and handleRequest

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!.

how to implement custom http session in java?

I will need to implement my own version of HttpSession in Java. I have found very little information which explains how achieve such a feat.
I guess my problem is - how do I override the existing HttpSession no matter the application server's implementation?
I did run across a quality but rather old read which helps me achieve my goal - http://java.sun.com/developer/technicalArticles/Servlets/ServletControl/
Are there any other approaches?
Its two ways.
"Wrapping" the original HttpSession in your own HttpServletRequestWrapper implementation.
I made this a short time ago for clustering distributed sessions with Hazelcast and Spring Session.
Here is explained pretty well.
First, implement your own HttpServletRequestWrapper
public class SessionRepositoryRequestWrapper extends HttpServletRequestWrapper {
public SessionRepositoryRequestWrapper(HttpServletRequest original) {
super(original);
}
public HttpSession getSession() {
return getSession(true);
}
public HttpSession getSession(boolean createNew) {
// create an HttpSession implementation from Spring Session
}
// ... other methods delegate to the original HttpServletRequest ...
}
After, from your own Filter, wraps the original HttpSession, and put it inside the FilterChain provided by your Servlet Container.
public class SessionRepositoryFilter implements Filter {
public doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
HttpServletRequest httpRequest = (HttpServletRequest) request;
SessionRepositoryRequestWrapper customRequest =
new SessionRepositoryRequestWrapper(httpRequest);
chain.doFilter(customRequest, response, chain);
}
// ...
}
Finally, set your Filter at the beginning in the web.xml to ensure it performs before any other.
The second manner to achieve it is providing to your Servlet Container your custom SessionManager.
For example, in Tomcat 7.
Create a new class, and implement HttpSession:
public class MyHttpSession implements javax.servlet.http.HttpSession {
// and implement all the methods
}
Disclaimer: I have not tested this myself:
Then write a filter with a url-pattern of /* and extend HttpServletRequestWrapper. Your wrapper should return your custom HttpSession class in getSession(boolean).
In the filter, use your own HttpServletRequestWrapper.
It doesn't seem like it's easily doable in a portable fashion that would work among different containers, since the HttpSession implementation is provided by the J2EE container.
However, to achieve a similar result, you can implement a javax.servlet.Filter and javax.servlet.HttpSessionListener and in your filter, wrap the ServletRequest and ServletResponse, such as described in Spring Boot with Hazelcast and Tomcat.

Categories