简体   繁体   中英

How do I get a subclass to use a parent class' protected methods?

I'm writing a front controller servlet class for webapps. The front controller is designed to differentiate between three basic cases:

  1. File request (calling a FileRequestHandler instance)
  2. Data request (calling a DataRequestHandler instance)
  3. Servlet request (calling a ServletRequestHandler instance)

For testing I wanted to use Tomcat's DefaultServlet ( javadoc , source code ) to serve files but I cannot get it to work. The problem is that even though my FileRequestHandler class should properly extend the DefaultServlet I cannot access its protected methods (specifically doGet for handling GET requests). The classes are in different packages btw.


Code:

public class FileRequestHandler extends DefaultServlet {

// fields

    private static final long serialVersionUID = 1L;

// methods

    public void setResponse(HttpServletRequest request , HttpServletResponse response, URI uri) 
            throws IOException, ServletException 
    {
                                                                                                                                    /* DEBUG */try {
            System.out.println("(!!) doGet >> " + DefaultServlet.class.getMethod("doGet",new Class[]{HttpServletRequest.class,HttpServletResponse.class}) ) ;
            doGet(request,response) ;
                                                                                                                                    /* DEBUG */}
                                                                                                                                    /* DEBUG */catch(Exception e) { System.out.println("(!) " + this.getClass( ).getName( ) + " >> buildResponse >> " + e.toString( ) ) ; }
    }

 }

Stack trace:

(part leading up to the NullPointer)

at org.apache.catalina.servlets.DefaultServlet.serveResource(DefaultServlet.java:741) at org.apache.catalina.servlets.DefaultServlet.doGet(DefaultServlet.java:398) at org.pulse.web.FileRequestHandler.buildResponse(FileRequestHandler.java:39)


Update:

I maybe have to clarify that the front controller servlet will intercept all HttpRequests, ( <url-pattern>/</url-pattern> in web.xml) to the effect that DefaultServlet instantiated by the servlet container will not receive any requests, as far as I can tell. I have now explicitely called DefaultServlet#init in the front controller class:

 FileRequestHandler fileRequestHandler = new FileRequestHandler( ) ;
 fileRequestHandler.init( ) ;

Now I end up with a 404 Servlet is not available.

Update2: The problem -- as turns out -- actually is a follow-up problem with inadequate use of the extended class rather than a direct problem with inheritance.


The post to the Log which I added to detect the problem's root will provoke a NoSuchMethodException . . If I omit it I'll get a NullPointerException .

It looks ever so simple. Still I can't get it to work the way I want it to. Any ideas, suggestions or insights?

TIA,

FK

Class.getMethod returns public methods - there's no such public method, hence the exception. You can use getDeclaredMethod to get non-public methods.

It's not clear why you were getting a NullPointerException when you tried it without the logging - if you can post a fuller stack trace, it may be clearer.

EDIT: Judging by the source code for DefaultServlet it looks like this is the line throwing the exception:

CacheEntry cacheEntry = resources.lookupCache(path);

That doesn't make much sense though, as init() should have thrown an exception in that case... is there anything else reporting an error in your logs?

You shouldn't have to do anything special in order to call a protected method from the superclass. In fact, since you haven't overridden doGet() in your servlet, its doGet() method should literally be the superclass method. You shouldn't have to do anything special, beyond calling it normally, like:

public void setResponse(HttpServletRequest request , HttpServletResponse response, URI uri) 
        throws IOException, ServletException  {

        doGet(request,response) ;
}

If you want you can replace doGet(request,response) with super.doGet(request,response) , but it will make no difference in this case because you have not overridden doGet() in your subclass.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM