我正在为Web应用程序编写前端控制器Servlet类。前端控制器旨在区分三种基本情况:
文件请求(调用FileRequestHandler
实例)
数据请求(调用DataRequestHandler
实例)
Servlet请求(调用ServletRequestHandler
实例)
为了进行测试,我想使用Tomcat的DefaultServlet
(javadoc,source code)来提供文件,但是我无法使其正常工作。问题是,即使我的FileRequestHandler
类应适当扩展DefaultServlet
,我也无法访问其受保护的方法(特别是doGet
用于处理GET请求)。这些类位于不同的程序包中。
码:
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( ) ) ; }
}
}
堆栈跟踪:
(导致NullPointer的部分)
在org.apache.catalina.servlets.DefaultServlet.serveResource(DefaultServlet.java:741)
在org.apache.catalina.servlets.DefaultServlet.doGet(DefaultServlet.java:398)
在org.pulse.web.FileRequestHandler.buildResponse(FileRequestHandler.java:39)
更新:
我可能不得不澄清一下,前端控制器servlet将拦截所有HttpRequest(在web.xml中为
<url-pattern>/</url-pattern>
),以致据我所知,由servlet容器实例化的DefaultServlet将不会接收任何请求。我现在在前端控制器类中显式调用了
DefaultServlet#init
: FileRequestHandler fileRequestHandler = new FileRequestHandler( ) ;
fileRequestHandler.init( ) ;
现在我最终得到一个404 Servlet不可用的信息。
Update2:问题-事实证明-实际上是后续问题,没有充分利用扩展类,而不是直接的继承问题。
我添加到日志中以检测问题根源的帖子会引起一个
NoSuchMethodException
。如果忽略它,则会得到一个NullPointerException
。看起来是如此简单。我仍然无法按照我想要的方式工作。有任何想法,建议或见解吗?
TIA,
FK
最佳答案
Class.getMethod
返回公共方法-没有这样的公共方法,因此是例外。您可以使用getDeclaredMethod
获取非公共方法。
目前尚不清楚为什么在没有日志的情况下尝试使用NullPointerException
的原因-如果您可以发布更完整的堆栈跟踪,则可能更清楚。
编辑:通过source code for DefaultServlet判断,看起来这是抛出异常的行:
CacheEntry cacheEntry = resources.lookupCache(path);
但这并没有多大意义,因为在这种情况下
init()
应该引发了异常...还有其他报告日志错误的信息吗?