一尘不染

Java JSP / Servlet:控制器Servlet抛出著名的堆栈溢出

jsp

我已经阅读了几份文档,但我听不懂:我知道我做错了什么,但我不明白。我有一个完全动态生成的网站:几乎没有静态内容。

因此,为了理解JSP / Servlet,我编写了自己的“前端控制器”来拦截每个查询,如下所示:

<servlet-mapping>
        <servlet-name>defaultservlet</servlet-name>
        <url-pattern>/*</url-pattern>
</servlet-mapping>

基本上,我需要任何用户请求,例如:

所有都经过我编写的默认servlet。

然后,该Servlet检查URI并查找必须将请求分派到哪个 .jsp ,然后在正确设置所有属性后执行以下操作:

RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/WEB-INF/jsp/index.jsp");
dispatcher.forward(req, resp);

当我使用url-pattern(在 web.xml中
)时,例如*.html,一切正常。但是,当我将其更改为/*(以真正拦截所有内容)时,我进入了一个无限循环,最后以…
StackOverflow结尾:

分派请求时,URI “ … / WEB-INF / jsp / index.jsp” 本身是否与我设置的 web.xml 过滤器/ * 相匹配?

编辑 显然没有,因为这是对 index.jsp 的精确映射,因此它绕过了web.xml url模式。所以我仍然不知道如何进入无尽的循环。

如果我想使用/ * url-pattern拦截所有内容但又能够调度/转发/,该怎么办?

我在这里不是在问规范/ Javadocs:我真的对更大的图景感到困惑,我需要对可能发生的事情进行一些解释。

我不应该拦截所有东西吗?

如果我可以拦截所有内容,那么关于转发/调度我应该注意些什么?


阅读 333

收藏
2020-06-08

共1个答案

一尘不染

不幸的是,Serlvet规范不允许创建Servlet映射来仅匹配传入请求,而不转发。但是,可以对过滤器映射执行此操作(默认情况下,过滤器映射仅匹配传入的请求)。

因此,使用单个servlet拦截所有内容的典型解决方案是使用UrlRewriteFilter

<filter>
    <filter-name>urlRewrite</filter-name>
    <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>urlRewrite</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<servlet>
    <servlet-name>application</servlet-name>
    <servlet-class>...</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>application</servlet-name>
    <url-pattern>/app/*</url-pattern>
</servlet-mapping>

/WEB-INF/urlrewrite.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite
    PUBLIC "-//tuckey.org//DTD UrlRewrite 3.0//EN"
    "http://tuckey.org/res/dtds/urlrewrite3.0.dtd">

<urlrewrite default-match-type="wildcard">
    <rule>
        <from>/**</from>
        <to>/app/$1</to>
    </rule>
    <outbound-rule>
        <from>/app/**</from>
        <to>/$1</to>
    </outbound-rule>    
</urlrewrite>

这种方式还允许您从/*静态文件的映射中指定例外。

2020-06-08