我正在为webapps编写一个前端控制器servlet类。前端控制器旨在区分三种基本情况:
FileRequestHandler
实例)DataRequestHandler
实例)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的部分)
at org.apache.catalina.servlets.DefaultServlet.serveResource(DefaultServlet.java:741) 在org.apache.catalina.servlets.DefaultServlet.doGet(DefaultServlet.java:398) at org.pulse.web.FileRequestHandler.buildResponse(FileRequestHandler.java:39)
更新
我可能必须澄清前端控制器servlet将拦截所有HttpRequests(web.xml中的<url-pattern>/</url-pattern>
),以便servlet容器实例化的DefaultServlet不会收到任何请求,尽我所能告诉。
我现在在前端控制器类中明确地调用了DefaultServlet#init
:
FileRequestHandler fileRequestHandler = new FileRequestHandler( ) ;
fileRequestHandler.init( ) ;
现在我最终得到了一个404 Servlet。
Update2:问题 - 事实证明 - 实际上是一个后续问题,因为扩展类的使用不充分而不是继承的直接问题。
我添加的用于检测问题根的日志的帖子会引发。如果我省略它,我会得到NoSuchMethodException
。NullPointerException
。
它看起来如此简单。我仍然无法按照我想要的方式工作。任何想法,建议或见解?
TIA,
FK
答案 0 :(得分:1)
Class.getMethod
返回 public 方法 - 没有这样的 public 方法,因此是例外。您可以使用getDeclaredMethod
获取非公开方法。
目前还不清楚为什么在没有记录的情况下尝试使用NullPointerException
时 - 如果可以发布更完整的堆栈跟踪,则可能更清楚。
编辑:从source code for DefaultServlet判断,看起来这是抛出异常的一行:
CacheEntry cacheEntry = resources.lookupCache(path);
虽然这没有多大意义,因为init()
应该在这种情况下抛出异常......你的日志中是否有其他报告错误的内容?
答案 1 :(得分:1)
为了从超类中调用受保护的方法,您不必执行任何特殊操作。实际上,由于您没有在servlet中重写doGet()
,因此它的doGet()
方法应该是超类方法。除了正常调用之外,您不应该做任何特别的事情,例如:
public void setResponse(HttpServletRequest request , HttpServletResponse response, URI uri)
throws IOException, ServletException {
doGet(request,response) ;
}
如果您愿意,可以将doGet(request,response)
替换为super.doGet(request,response)
,但在这种情况下它没有任何区别,因为您没有在子类中覆盖doGet()
。