Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/svn/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何让子类使用父类';保护方法?_Java_Inheritance_Methods_Subclass_Protected - Fatal编程技术网

Java 如何让子类使用父类';保护方法?

Java 如何让子类使用父类';保护方法?,java,inheritance,methods,subclass,protected,Java,Inheritance,Methods,Subclass,Protected,我正在为webapps编写一个前端控制器servlet类。前控制器设计用于区分三种基本情况: 文件请求(调用FileRequestHandler实例) 数据请求(调用DataRequestHandler实例) Servlet请求(调用ServletRequestHandler实例) 为了进行测试,我想使用Tomcat的DefaultServlet(,)来提供文件,但我无法让它工作。问题是,即使我的FileRequestHandler类应该正确地扩展DefaultServlet,我也无法访问其受保

我正在为webapps编写一个前端控制器servlet类。前控制器设计用于区分三种基本情况:

  • 文件请求(调用
    FileRequestHandler
    实例)
  • 数据请求(调用
    DataRequestHandler
    实例)
  • Servlet请求(调用
    ServletRequestHandler
    实例)
  • 为了进行测试,我想使用Tomcat的
    DefaultServlet
    (,)来提供文件,但我无法让它工作。问题是,即使我的
    FileRequestHandler
    类应该正确地扩展
    DefaultServlet
    ,我也无法访问其受保护的方法(特别是用于处理GET请求的
    doGet
    )。顺便说一句,这些类在不同的包中


    代码:

    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( ) ) ; }
        }
    
     }
    

    堆栈跟踪:

    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( ) ) ; }
        }
    
     }
    
    (指向空指针的部分)

    位于org.apache.catalina.servlets.DefaultServlet.ServerResource(DefaultServlet.java:741) 位于org.apache.catalina.servlets.DefaultServlet.doGet(DefaultServlet.java:398) 位于org.pulse.web.FileRequestHandler.buildResponse(FileRequestHandler.java:39)


    更新:

    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( ) ) ; }
        }
    
     }
    
    我可能必须澄清,前端控制器servlet将拦截所有httprequest,(
    /
    在web.xml中),据我所知,servlet容器实例化的DefaultServlet不会接收任何请求。 我现在在front controller类中明确地调用了
    DefaultServlet#init

     FileRequestHandler fileRequestHandler = new FileRequestHandler( ) ;
     fileRequestHandler.init( ) ;
    
    现在我以404servlet不可用而告终

    Update2:事实证明,这个问题实际上是扩展类使用不足的后续问题,而不是继承的直接问题


    我为检测问题根源而添加的日志帖子将引发
    NoSuchMethodException
    。。如果我忽略它,我将得到一个
    NullPointerException

    它看起来非常简单。但我还是不能让它按我想要的方式工作。有什么想法、建议或见解吗

    蒂亚


    FK

    Class.getMethod返回公共方法-没有这样的公共方法,因此出现异常。您可以使用
    getDeclaredMethod
    获取非公共方法

    不清楚为什么在没有日志记录的情况下尝试时会出现
    NullPointerException
    ——如果可以发布更完整的堆栈跟踪,可能会更清楚

    编辑:从代码判断,这是引发异常的行:

    CacheEntry cacheEntry = resources.lookupCache(path);
    

    不过,这没有多大意义,因为在这种情况下,
    init()
    应该引发异常。。。日志中是否还有其他报告错误的内容?

    从超类调用受保护的方法不需要做任何特殊的操作。事实上,由于您没有在servlet中重写
    doGet()
    ,因此它的
    doGet()
    方法实际上应该是超类方法。除了正常的称呼之外,你不应该做任何特殊的事情,比如:

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

    如果需要,您可以用
    super.doGet(request,response)
    替换
    doGet(request,response)
    ,但是在这种情况下没有什么区别,因为您没有重写子类中的
    doGet()

    更新了我的帖子。顺便说一句,
    request
    response
    都不为空。@FK82:您使用的是什么版本的Tomcat?@John Skeet:我需要明确地调用
    init
    吗?根据文档(),Servlet容器通常会这样做。@FK82:不需要,不需要。作为Servlet生命周期的一部分,应该自动调用它。在发生此异常之前,您的日志中有什么有趣的地方吗?@John Skeet:没有什么特别的地方—到NullPointer的堆栈跟踪是预期的方法调用链。请看一下我的更新。是的,我也是这么想的。:-)