getRequestDispatcher(.).forward(req,res) 抛出 java.io.FileNotFoundException

getRequestDispatcher(.).forward(req,res) throws java.io.FileNotFoundException

我已将我的 Servlet 从 2.4 升级到 3.0,并在 Websphere 8.5.5.8 上部署了我的应用程序。应用服务器正常启动。 当我尝试在浏览器中访问我的 home.jsp 页面时,它抛出:

Controller Main Error OG1000SRVE0190E: File not found: /servlet/com.platform7.affina.operations.servlet.ValidateLoginUser

当我尝试调试时,代码命中了我的主控制器 Servlet(在同一个包中)但在控制器 servlet 中 class 我正在调用:

this.getServletContext().getRequestDispatcher("Servlet/com.platform7.affina.operations.servlet.ValidateLoginUser").forward(request, response);

抛出:

FileNotFoundException for Servlet/com.platform7.affina.operations.servlet.ValidateLoginUser.

但是 ValidateLoginUser 在同一个包中并且 classes 文件夹位置!

文件夹结构:

\NEED4SPEEDCell02\operations_1.ear\OperationsWeb.war\WEB-INF\classes\com\platform7\affina\operations\servlet

ControllerMain.classValidateLoginUser.class 在同一个 servlet 包中。

我的Web.xml文件:

<servlet>
    <servlet-name>servletMain</servlet-name>
    <servlet-class>com.platform7.affina.operations.servlet.ControllerMain</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>servletMain</servlet-name>
    <url-pattern>/controllerMain</url-pattern>
</servlet-mapping>

所以当我访问我的 URL 时:它命中 ControllerMain.class 但在这个 class 中我正在调用另一个 servlet,它不是 web.xml 的一部分但位于ControllerMain.class.

同包

当我打印真实路径时:this.getServletContext().getRealPath("/"));

我得到:

C:\WebSphere858\AppServer\profiles\AppSrv01\installedApps\NEED4SPEEDCell02\operations_1.ear\OperationsWeb.war

我也尝试使用 getNamedDispatcher(..) 但抛出:null.

相同的代码在 Websphere 7 上运行良好,甚至在 Websphere 8.5.5.5 上运行

您似乎依赖于已知存在重大安全漏洞的遗留 InvokerServlet。这在 Tomcat 5 和克隆 (WebSphere 4) 中已弃用,并在 Tomcat 7 和克隆 (WebSphere 6) 中删除。

你不应该再使用它了。只需将 servlet 映射到正常的 URL 模式并调用它。假设 servlet 通过 servlet class 上的 @WebServlet("/validateLoginUser") 注释或 web.xml 映射中的 <url-pattern>/validateLoginUser</url-pattern> 映射到 /validateLoginUser 的 URL 模式在 servlet 上,然后您可以获得一个请求调度程序,如下所示:

request.getRequestDispatcher("/validateLoginUser");

或者,只需将共享代码重构为带有方法的普通 Java class 并以通常的 Java 方式调用它。现在在 servlet 中紧密耦合共享验证逻辑有点奇怪。

另请参阅:

  • How to invoke a servlet without mapping in web.xml?

由于 security reasonscom.ibm.ws.webcontainer.disallowServeServletsByClassname 属性 的默认设置已更改。

Please Note:This APAR has changed the default value of the WebContainer custom property com.ibm.ws.webcontainer.disallowServeServletsByClassname from false to true so that no security threat could occur. Prior to this change, it was up to the developer to remember to change the custom property to true before deploying into production.

Property Name: com.ibm.ws.webcontainer.disallowServeServletsByClassname Description: If set to true, disallows the use of serveServletsByClassnameEnabled at the application server level, overriding any setting of serveServletsByClassnameEnabled at the application level. This property affects all applications. Values: true(default)/false

您需要将该自定义 属性 添加到 Web 容器并将其设置为 false 以便按 class 名称提供 servlet。

但是正如 BalusC 所建议的那样,您应该以以下形式将您的 servlet 添加到 web.xml

<servlet>
    <servlet-name>servletMain</servlet-name>
    <servlet-class>com.platform7.affina.operations.servlet.ValidateLoginUser</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>servletMain</servlet-name>
    <url-pattern>/validateLoginUser</url-pattern>
</servlet-mapping>

并将转发更改为:

this.getServletContext().getRequestDispatcher("/validateLoginUser").forward(request, response);

对来自同一个包裹的另一个 class 做同样的事情。

为了使上述升级工作,我做了一些其他更改,如下所示,以供将来参考。

主要是,我必须更改 websphere 的绑定文件。 以前,我有两个绑定 ibm-web-bnd.xmiibm-web-ext.xmi

ibm-web-bnd.xmi

<?xml version="1.0" encoding="UTF-8"?>
<com.ibm.ejs.models.base.bindings.webappbnd:WebAppBinding xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:com.ibm.ejs.models.base.bindings.webappbnd="webappbnd.xmi" xmi:id="WebAppBinding_1226331113121" virtualHostName="default_host">
  <webapp href="WEB-INF/web.xml#WebApp"/>
    <resRefBindings xmi:id="ResourceRefBinding_1226331113121" jndiName="AffinaDataSource_pma">
      <bindingResourceRef href="WEB-INF/web.xml#ResourceRef_AffinaDataSource_pma"/>
    </resRefBindings>
</com.ibm.ejs.models.base.bindings.webappbnd:WebAppBinding>

ibm-web-ext.xmi

<?xml version="1.0" encoding="UTF-8"?>
<com.ibm.ejs.models.base.extensions.webappext:WebAppExtension 
    xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" 
    xmlns:com.ibm.ejs.models.base.extensions.webappext="webappext.xmi" 
    xmi:id="WebAppExtension_1226331113121"
    serveServletsByClassnameEnabled="true">
  <webApp href="WEB-INF/web.xml#WebApp"/>
  <jspAttributes xmi:id="JSPAttribute_1226331113121" name="reloadEnabled" value="true"/>
  <jspAttributes xmi:id="JSPAttribute_1226331113122" name="reloadInterval" value="10"/>
</com.ibm.ejs.models.base.extensions.webappext:WebAppExtension>

因此,根据 servlet3 和 Websphere 8.5.5.8,我将上述两个 .xmi 文件替换为 ibm-web-bnd.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-bnd xmlns="http://websphere.ibm.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-bnd_1_0.xsd" version="1.0">

  <virtual-host name="default_host"/>
  <resource-ref name="AffinaDataSourceAlias_pma" binding-name="AffinaDataSource_pma"/>

</web-bnd>

然后在 Websphere 8.5.5.8 上安装应用程序时,它会抛出内存不足错误,因此为了解决这个问题,我在 wsadmin.bat

中将最大内存参数从 256m 更改为 512m

C:\WebSphere858\AppServer\bin\wsadmin.bat

set PERFJAVAOPTION=-Xms256m -Xmx512m -Xquickstart

希望对您有所帮助。