Java 如何让子类使用父类';保护方法?
我正在为webapps编写一个前端控制器servlet类。前控制器设计用于区分三种基本情况:Java 如何让子类使用父类';保护方法?,java,inheritance,methods,subclass,protected,Java,Inheritance,Methods,Subclass,Protected,我正在为webapps编写一个前端控制器servlet类。前控制器设计用于区分三种基本情况: 文件请求(调用FileRequestHandler实例) 数据请求(调用DataRequestHandler实例) Servlet请求(调用ServletRequestHandler实例) 为了进行测试,我想使用Tomcat的DefaultServlet(,)来提供文件,但我无法让它工作。问题是,即使我的FileRequestHandler类应该正确地扩展DefaultServlet,我也无法访问其受保
FileRequestHandler
实例)DataRequestHandler
实例)ServletRequestHandler
实例)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
它看起来非常简单。但我还是不能让它按我想要的方式工作。有什么想法、建议或见解吗
蒂亚
FKClass.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的堆栈跟踪是预期的方法调用链。请看一下我的更新。是的,我也是这么想的。:-)