Java url模式/*将jsp文件和静态资产作为单独的请求提供

Java url模式/*将jsp文件和静态资产作为单独的请求提供,java,tomcat,servlets,web.xml,url-pattern,Java,Tomcat,Servlets,Web.xml,Url Pattern,我有一个简单的servlet,它根据不同的地理位置呈现不同的内容 例如: example.com/us example.com/de example.com/uk example.com/.. 因此,实际上servlet应该支持所有地理位置作为url模式。因此,我在web.xml文件中定义了以下规则: <servlet-mapping> servlet-name>MyServlet</servlet-name> <url-pattern>/*&

我有一个简单的servlet,它根据不同的地理位置呈现不同的内容 例如:

example.com/us
example.com/de
example.com/uk
example.com/..
因此,实际上servlet应该支持所有地理位置作为url模式。因此,我在
web.xml
文件中定义了以下规则:

<servlet-mapping>
  servlet-name>MyServlet</servlet-name>
  <url-pattern>/*</url-pattern>
</servlet-mapping>
只要我尝试转发页面,servlet就会一次又一次地启动;它还尝试处理请求
/page/show.jsp
。 因此,当我尝试访问
example.com/us
时,会得到这样一个输出:

servlet initiated... ~> /us
servlet initiated... ~> /page/show.jsp
Exception...
servlet initiated... ~> /page/show.jsp
Exception...
servlet initiated... ~> /page/show.jsp
...
它引发了一个异常,因为我的servlet不需要这样的url模式
/page/show.jsp
,但它会触发,因为我在web.xml文件中定义了
/*
url模式


有什么想法吗?如何跳过或排除上述不需要的请求?谢谢。

我找不到具体的参考,但我认为“/*”根url模式与global web.xml中的默认映射冲突,这可能是您的问题的原因

<servlet>
    <servlet-name>default</servlet-name>
    <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
    <init-param>
        <param-name>debug</param-name>
        <param-value>0</param-value>
    </init-param>
    <init-param>
        <param-name>listings</param-name>
        <param-value>false</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<!-- The mapping for the default servlet -->
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>showpage</servlet-name>
<jsp-file>/pages/show.jsp</jsp-file>
</servlet>

<servlet-mapping>
<servlet-name>showpage</servlet-name>
<url-pattern>/show</url-pattern>
</servlet-mapping>

违约
org.apache.catalina.servlets.DefaultServlet
调试
0
列表
假的
1.
违约
/
尝试添加显式JSPServlet标记和servlet映射,以避免通过使用“/”根url模式创建的默认映射来处理jsp。我不确定这是否能解决你的问题

<servlet>
    <servlet-name>default</servlet-name>
    <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
    <init-param>
        <param-name>debug</param-name>
        <param-value>0</param-value>
    </init-param>
    <init-param>
        <param-name>listings</param-name>
        <param-value>false</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<!-- The mapping for the default servlet -->
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>showpage</servlet-name>
<jsp-file>/pages/show.jsp</jsp-file>
</servlet>

<servlet-mapping>
<servlet-name>showpage</servlet-name>
<url-pattern>/show</url-pattern>
</servlet-mapping>

展示页
/pages/show.jsp
展示页
/展示
另一个更明确的解决方案是创建一个url模式,区分所有国家的地理位置请求

<servlet-mapping>
    <servlet-name>MyServlet</servlet-name>
    <url-pattern>/geo/*</url-pattern>
</servlet-mapping>

MyServlet
/地理位置/*
因此example.com/geo/us等将明确映射


我尝试了相同的全局设置,遇到了一个类似的问题,它递归地尝试请求并反复抛出异常,直到我停止Tomcat服务器。当使用更具体的url模式时,问题得到解决。

当解析pages/show.jsp时,容器将首先匹配最长路径,然后查看文件扩展名(.jsp)。因此pages/show.jsp与/*匹配,因此容器再次加载Servlet,而不会启动jsp引擎Servlet

所有JSP都在pages目录中吗?也许可以将该映射添加到web.xml中

<servlet-mapping>
    <servlet-name>jsp</servlet-name>
    <url-pattern>/pages/*</url-pattern>
</servlet-mapping>

jsp
/页数/*

根据servlet规范(此处为2.5,但新版本应为smae):

  • 容器将尝试找到请求路径与 servlet的路径。成功匹配将选择servlet
  • 容器将递归地尝试匹配最长路径前缀。这已经完成了 通过使用“/”字符作为 路径分隔符。最长匹配确定所选的servlet
  • 如果URL路径中的最后一段包含扩展名(例如.jsp),则servlet 容器将尝试匹配处理扩展请求的servlet。 扩展名定义为最后一个“.”字符后最后一段的一部分
  • 如果前三条规则都没有导致servlet匹配,那么容器将 尝试提供适合所请求资源的内容。如果是“默认” servlet是为应用程序定义的,将使用它
  • (来源:)

    因此,对于您的情况,添加更精确的映射(如Si Kelly所说)就足够了:

    
    jsp
    /pages/show.jsp
    
    巴特的回答给了我线索。实际上有很多方法可以处理这个问题,一种是使用
    过滤器,另一种是在
    web.xml
    中定义所有静态路由,而不是我使用的
    /*

    因此,为了解决这个问题,我将url模式更改如下:

    <!-- static assets -->
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.js</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.css</url-pattern>
    </servlet-mapping>
    
    <!-- my servlet -->
    <servlet-mapping>
      servlet-name>MyServlet</servlet-name>
      <url-pattern>/</url-pattern>
    </servlet-mapping>
    
    
    违约
    *.js
    违约
    *.css
    servlet名称>MyServlet
    /
    
    您也不需要为
    org.apache.catalina.servlets.DefaultServlet定义模式,默认情况下它已经存在了。
    
    因此,在上述更改之后,一切正常。

    您的异常是什么?@erencan:异常抱怨
    /page/show.jsp
    请求。因此,在
    /us
    之后,我希望servlet停止,不要处理其他请求,比如
    /page/show.jsp
    您的问题不清楚。您已经将请求重定向到
    /pages/show.jsp
    ,我想您还没有发布所有代码,正是引发异常的代码。