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

时间:2010-06-01 02:32:47

标签: java jsp servlets

我已经阅读了几篇文档但我没理解:我知道我做错了但我不明白。我有一个完全动态生成的网站:几乎没有任何静态内容。

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

<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并找到必须分派的 .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-pattern。所以我仍然无法得到如何进入无限循环。

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

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

我不应该拦截真的一切吗?

如果我可以截取所有内容,我应该注意哪些转发/调度?

2 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:0)

尝试使用内置前控制器模式的struts。在那里你将有一个动作类,你可以在struts-config文件中定义前进,使用它可以轻松管理前锋。

完成教程http://www.roseindia.net/struts/struts2/index.shtml。希望这会对你有所帮助。