Java JSP/Servlet : controller servlet throwing the famous stack overflow

标签 java jsp servlets

我读过几个文档,但我不明白:我知道我做错了什么,但我不明白是什么。我有一个完全动态生成的网站:几乎没有任何静态内容。

因此,为了理解 JSP/Servlet,我编写了自己的“前端 Controller ”来拦截每个查询,它看起来像这样:

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

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

  • example.org
  • example.org/bar
  • example.org/foo.html

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

然后 servlet 检查 URI 并找到必须将请求分派(dispatch)到哪个 .jsp,然后在正确设置所有属性后执行:

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

当我使用 url 模式(在 web.xml 中)时,比如 *.html,一切正常。但是当我将它更改为 /* (真正拦截所有内容)时,我进入了一个无限循环,它以... StackOverflow :)

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

EDIT 显然,不,因为这是到 index.jsp 的精确映射,因此它绕过了 web.xml url 模式。所以我仍然不明白如何进入那个无限循环。

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

我在这里不是在询问规范/Javadocs:我真的对大局感到困惑,我需要一些关于可能发生的事情的解释。

我真的不应该拦截所有内容吗?

如果我可以拦截一切,我应该注意转发/调度什么?

最佳答案

不幸的是,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>

这种方式还允许您为静态文件指定 /* 映射的异常(exception)情况。

关于Java JSP/Servlet : controller servlet throwing the famous stack overflow,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2946995/

相关文章:

java - if 语句可以嵌套在 while 循环中吗?

java - 在 iText 中使用制表符缩进多行字符串

java - 在html(servlet/jsp)中打印jena结果集

java - 如何替换执行 ActionForward 方法

java - org.apache.catalina.LifecycleException tomcat错误

java - servlet 支持两种输出格式的标准做法

java - 在返回响应之前获取 servlet 请求的状态

java - 如何估计调用 System.gc() 时剩余的内存量?

java - request.getParameter() 在 servlet 中返回 null,除了一个参数

java - 如何将用户重定向到登录屏幕,如果在 session 超时后收到 ajax 调用