是否可以让 <error-page> servlet 忽略某些请求?
Posted
技术标签:
【中文标题】是否可以让 <error-page> servlet 忽略某些请求?【英文标题】:Is it possible to have the <error-page> servlet ignore some requests? 【发布时间】:2013-11-18 20:40:15 【问题描述】:我有一个应用程序使用该功能为带有一些错误状态代码的 html 页面提供服务,例如 404。但是,一些请求是诸如 restful 服务或图像之类的东西,它们应该返回由 restful 服务提供的 JSON,或者什么都不返回在图像的情况下。我使用 Tomcat 作为 servlet 容器。
为了澄清,有几个 servlet,一些提供图像,另一些提供 html,以及一个过滤器,为用户可以配置的各种路径提供 html。 404 状态通常来自缺少映射到请求路径的过滤器或 servlet。因此,错误页面功能可以方便地为没有过滤器或 servlet 响应的路径提供响应。
所以我在 web.xml 中的内容是(忽略 / 和 * 之间的空格):
... several other mappings above
<servlet-mapping>
<servlet-name>RestServlet</servlet-name>
<url-pattern>/servlet/rest/ *</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ErrorPageServlet</servlet-name>
<url-pattern>/servlet/errorPage/ *</url-pattern>
</servlet-mapping>
...
<filter-mapping>
<!--This will serve content and not forward to the filter chain for certain paths-->
<filter-name>MainFilter</filter-name>
<url-pattern>/ *</url-pattern>
</filter-mapping>
...
<error-page>
<!--Page not found-->
<error-code>404</error-code>
<location>/servlet/errorPage/404</location>
</error-page>
是否可以让错误页面 servlet 忽略某些请求但在响应中为其他请求提供 html?或者我应该使用一些不同的方法来传递错误页面?
澄清一下,我想要的是,如果有人 GET /foo(不存在)它会转到 ErrorPageServlet,但对于 GET /servlet/rest/foo/bar 返回 404 响应代码,它不会转到ErrorPageServlet。
【问题讨论】:
【参考方案1】:我终于弄清楚了问题所在。宁静的服务调用HttpServletResponse.sendError()
而不是HttpServletResponse.setStatus()
。事实证明,两者之间存在巨大差异,只有 sendError()
导致使用 servlet。
解决方法很简单,如果你想让错误页面处理输出,使用sendError()
,如果你想在当前servlet中写入输出,使用setStatus()
。
【讨论】:
【参考方案2】:首先您应该设置您的 web.xml 以将错误 404 重定向到特定页面:
<error-page>
<error-code>404</error-code>
<location>/error404.jsp</location>
</error-page>
此时,您可以按如下方式实现您的error404.jsp:
<%@ page language="java" isErrorPage="true" %><%
String url = (String) request.getAttribute("javax.servlet.forward.servlet_path") ;
if ( url!=null && url.indexOf("restRequest")!=-1 ) return ;
%>
<html><head><title>Error 404</title></head><body>Error 404<br>The requested URL <%=url%> was not found on this server.</body></html>
【讨论】:
问题在于,restful 服务写入响应的数据丢失了,因为 /errro404.jsp 获取的是一个新的响应对象,您实际上是在没有输出的情况下返回它。 @SindriTraustason 不确定您的意思。在我这边,在同一个 webapp 上拥有一个网站和 restfull 服务,这种 jsp 错误页面(如 kkk 示例)是在整个网站的 web.xml 中保留此功能的唯一解决方案(避免 tomcat 默认消息和 tomcat 版本) .另外我映射了restservice异常,cf。 codingpedia.org/ama/error-handling-in-rest-api-with-jersey【参考方案3】:您可以通过简单的 web.xml 映射来实现它。例子是
<servlet>
<servlet-name>ExceptionServlet</servlet-name>
<servlet-class>examples.Exception</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ExceptionServlet</servlet-name>
<url-pattern>/errorCodeRequest</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>JsonServlet</servlet-name>
<servlet-class>examples.JSON</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>JsonServlet</servlet-name>
<url-pattern>/restRequest</url-pattern>
</servlet-mapping>
【讨论】:
我看不出这有什么帮助,要求是为除 /restRequest/** 之外的所有请求提供 404 响应的 html 正文以上是关于是否可以让 <error-page> servlet 忽略某些请求?的主要内容,如果未能解决你的问题,请参考以下文章
spring mvc 通过<error-page>处理404,怎么记录造成404的请求
如何在 servlet 3.0 的 web.xml-less 中定义 <welcome-file-list> 和 <error-page>?