显示通过Jetty 9.4发送到JSP的PUT请求的自定义错误页面

如何解决显示通过Jetty 9.4发送到JSP的PUT请求的自定义错误页面

背景

从Spring 4升级到5.3时,web.xml中指定的错误页面不再适用于某些HTTP谓词,其中之一是PUT。例如,当对Spring控制器的PUT请求导致意外错误时,则不会显示web.xml中定义的错误页面。取而代之的是,我们在405 Method Not Allowed处出现了错误。错误页面已正确显示GET个请求。错误页面在web.xml中已经(并且仍然)是这样定义的:

<error-page>
    <exception-type>java.lang.Exception</exception-type>
    <location>/uncaughtException</location>
</error-page>

“ uncaughtException”是这样定义的切片视图:

<definition extends="siteDefault" name="uncaughtException">
     <put-attribute name="body" value="/WEB-INF/views/uncaughtException.jspx"/>
</definition>

为了使此功能适用于所有HTTP动词,我们添加了以下Spring Controller:

@RequestMapping("/uncaughtException")
@Controller
public class UncaughtExceptionViewController {

    @RequestMapping
    public String uncaughtException() {
        return "uncaughtException";
    }

}

现在,即使对于PUT请求,错误页面也能正确显示。

以前,我们使用Jetty 9.2,但是在升级到Java 14时,我们还被迫升级到Jetty 9.4。这样做时,我们注意到即使我们仍然拥有PUT控制器,也不再为GET请求显示错误页面(它对UncaughtExceptionViewController有效)。相反,405 Method Not Allowed错误又回来了。在调试期间,我们注意到使用Jetty 9.4时uncaughtException中的UncaughtExceptionViewController没有被调用。

问题

我们如何配置Jetty或Spring MVC来显示错误页面,甚至对于PUT请求,不仅显示GET,而且不显示405 Method Not Allowed

更新

org.eclipse.jetty.server.Response.setStatus中设置了一个断点之后,我发现问题似乎在于“ JSP仅允许GET,POST或HEAD。Jasper也允许选择”。完整的堆栈跟踪为:

sendError:454,Response (org.eclipse.jetty.server)
sendError:158,HttpServletResponseWrapper (javax.servlet.http)
sendError:119,OnCommittedResponseWrapper (org.springframework.session.web.http)
sendError:158,HttpServletResponseWrapper (javax.servlet.http)
sendError:158,OnCommittedResponseWrapper (org.springframework.security.web.util)
sendError:158,OnCommittedResponseWrapper (org.springframework.security.web.util)
_jspService:1,site_005fdefault_jspx (org.apache.jsp.WEB_002dINF.layouts)
service:71,HttpJspBase (org.apache.jasper.runtime)
service:790,HttpServlet (javax.servlet.http)
service:476,JspServletWrapper (org.apache.jasper.servlet)
serviceJspFile:386,JspServlet (org.apache.jasper.servlet)
service:330,JspServlet (org.apache.jasper.servlet)
service:106,JettyJspServlet (org.eclipse.jetty.jsp)
service:790,HttpServlet (javax.servlet.http)
service:1402,ServletHolder$NotAsyncServlet (org.eclipse.jetty.servlet)
handle:763,ServletHolder (org.eclipse.jetty.servlet)
doHandle:569,ServletHandler (org.eclipse.jetty.servlet)
handle:143,ScopedHandler (org.eclipse.jetty.server.handler)
handle:620,SecurityHandler (org.eclipse.jetty.security)
handle:127,HandlerWrapper (org.eclipse.jetty.server.handler)
nextHandle:235,ScopedHandler (org.eclipse.jetty.server.handler)
doHandle:1610,SessionHandler (org.eclipse.jetty.server.session)
nextHandle:233,ScopedHandler (org.eclipse.jetty.server.handler)
doHandle:1377,ContextHandler (org.eclipse.jetty.server.handler)
nextScope:188,ScopedHandler (org.eclipse.jetty.server.handler)
doScope:507,ServletHandler (org.eclipse.jetty.servlet)
doScope:1580,SessionHandler (org.eclipse.jetty.server.session)
nextScope:186,ScopedHandler (org.eclipse.jetty.server.handler)
doScope:1292,ContextHandler (org.eclipse.jetty.server.handler)
handle:141,ScopedHandler (org.eclipse.jetty.server.handler)
forward:219,Dispatcher (org.eclipse.jetty.server)
forward:78,Dispatcher (org.eclipse.jetty.server)
forward:407,SessionRepositoryFilter$SessionRepositoryRequestWrapper$SessionCommittingRequestDispatcher (org.springframework.session.web.http)
forward:265,ServletRequest (org.apache.tiles.request.servlet)
doForward:228,ServletRequest (org.apache.tiles.request.servlet)
dispatch:57,AbstractClientRequest (org.apache.tiles.request)
render:47,DispatchRenderer (org.apache.tiles.request.render)
render:259,BasicTilesContainer (org.apache.tiles.impl)
render:397,BasicTilesContainer (org.apache.tiles.impl)
render:238,BasicTilesContainer (org.apache.tiles.impl)
render:221,BasicTilesContainer (org.apache.tiles.impl)
render:59,DefinitionRenderer (org.apache.tiles.renderer)
renderMergedOutputModel:147,TilesView (org.springframework.web.servlet.view.tiles3)
render:316,AbstractView (org.springframework.web.servlet.view)
render:1373,DispatcherServlet (org.springframework.web.servlet)
processDispatchResult:1118,DispatcherServlet (org.springframework.web.servlet)
doDispatch:1057,DispatcherServlet (org.springframework.web.servlet)
doService:943,DispatcherServlet (org.springframework.web.servlet)
processRequest:1006,FrameworkServlet (org.springframework.web.servlet)
doPut:920,FrameworkServlet (org.springframework.web.servlet)
service:710,HttpServlet (javax.servlet.http)
service:883,FrameworkServlet (org.springframework.web.servlet)
service:790,HttpServlet (javax.servlet.http)
handle:763,ServletHolder (org.eclipse.jetty.servlet)
doFilter:1651,ServletHandler$CachedChain (org.eclipse.jetty.servlet)
doFilter:226,WebSocketUpgradeFilter (org.eclipse.jetty.websocket.server)
doFilter:1638,ServletHandler$CachedChain (org.eclipse.jetty.servlet)
doFilterInternal:186,OpenEntityManagerInViewFilter (org.springframework.orm.jpa.support)
doFilter:119,OncePerRequestFilter (org.springframework.web.filter)
doFilter:1638,ServletHandler$CachedChain (org.eclipse.jetty.servlet)
doFilter:317,FilterChainProxy$VirtualFilterChain (org.springframework.security.web)
invoke:127,FilterSecurityInterceptor (org.springframework.security.web.access.intercept)
doFilter:91,FilterSecurityInterceptor (org.springframework.security.web.access.intercept)
doFilter:331,FilterChainProxy$VirtualFilterChain (org.springframework.security.web)
doFilter:114,ExceptionTranslationFilter (org.springframework.security.web.access)
doFilter:331,FilterChainProxy$VirtualFilterChain (org.springframework.security.web)
doFilter:137,SessionManagementFilter (org.springframework.security.web.session)
doFilter:331,FilterChainProxy$VirtualFilterChain (org.springframework.security.web)
doFilter:111,AnonymousAuthenticationFilter (org.springframework.security.web.authentication)
doFilter:331,FilterChainProxy$VirtualFilterChain (org.springframework.security.web)
doFilter:158,RememberMeAuthenticationFilter (org.springframework.security.web.authentication.rememberme)
doFilter:331,FilterChainProxy$VirtualFilterChain (org.springframework.security.web)
doFilter:170,SecurityContextHolderAwareRequestFilter (org.springframework.security.web.servletapi)
doFilter:331,FilterChainProxy$VirtualFilterChain (org.springframework.security.web)
doFilter:63,RequestCacheAwareFilter (org.springframework.security.web.savedrequest)
doFilter:331,FilterChainProxy$VirtualFilterChain (org.springframework.security.web)
doFilterInternal:158,BasicAuthenticationFilter (org.springframework.security.web.authentication.www)
doFilter:119,OncePerRequestFilter (org.springframework.web.filter)
doFilter:331,FilterChainProxy$VirtualFilterChain (org.springframework.security.web)
doFilter:200,AbstractAuthenticationProcessingFilter (org.springframework.security.web.authentication)
doFilter:331,FilterChainProxy$VirtualFilterChain (org.springframework.security.web)
doFilter:116,LogoutFilter (org.springframework.security.web.authentication.logout)
doFilter:331,FilterChainProxy$VirtualFilterChain (org.springframework.security.web)
doFilterInternal:66,HeaderWriterFilter (org.springframework.security.web.header)
doFilter:119,FilterChainProxy$VirtualFilterChain (org.springframework.security.web)
doFilterInternal:56,WebAsyncManagerIntegrationFilter (org.springframework.security.web.context.request.async)
doFilter:119,FilterChainProxy$VirtualFilterChain (org.springframework.security.web)
doFilter:105,SecurityContextPersistenceFilter (org.springframework.security.web.context)
doFilter:331,FilterChainProxy$VirtualFilterChain (org.springframework.security.web)
doFilterInternal:214,FilterChainProxy (org.springframework.security.web)
doFilter:177,FilterChainProxy (org.springframework.security.web)
invokeDelegate:358,DelegatingFilterProxy (org.springframework.web.filter)
doFilter:271,DelegatingFilterProxy (org.springframework.web.filter)
doFilter:1638,ServletHandler$CachedChain (org.eclipse.jetty.servlet)
doFilterInternal:94,HiddenHttpMethodFilter (org.springframework.web.filter)
doFilter:119,ServletHandler$CachedChain (org.eclipse.jetty.servlet)
doFilterInternal:201,CharacterEncodingFilter (org.springframework.web.filter)
doFilter:119,ServletHandler$CachedChain (org.eclipse.jetty.servlet)
doFilterInternal:40,CorsFilter (com.mycompany.spring)
doFilter:119,ServletHandler$CachedChain (org.eclipse.jetty.servlet)
doFilterInternal:141,SessionRepositoryFilter (org.springframework.session.web.http)
doFilter:82,OncePerRequestFilter (org.springframework.session.web.http)
invokeDelegate:358,ServletHandler$CachedChain (org.eclipse.jetty.servlet)
doHandle:567,ScopedHandler (org.eclipse.jetty.server.handler)
handle:578,ScopedHandler (org.eclipse.jetty.server.handler)
handle:191,ContextHandlerCollection (org.eclipse.jetty.server.handler)
handle:146,HandlerCollection (org.eclipse.jetty.server.handler)
handle:127,HandlerWrapper (org.eclipse.jetty.server.handler)
handle:501,Server (org.eclipse.jetty.server)
lambda$handle$1:383,HttpChannel (org.eclipse.jetty.server)
dispatch:-1,435181768 (org.eclipse.jetty.server.HttpChannel$$Lambda$1064)
dispatch:556,HttpChannel (org.eclipse.jetty.server)
handle:375,HttpChannel (org.eclipse.jetty.server)
onFillable:273,HttpConnection (org.eclipse.jetty.server)
succeeded:311,AbstractConnection$ReadCallback (org.eclipse.jetty.io)
fillable:105,FillInterest (org.eclipse.jetty.io)
run:104,ChannelEndPoint$1 (org.eclipse.jetty.io)
runTask:336,EatWhatYouKill (org.eclipse.jetty.util.thread.strategy)
doProduce:313,EatWhatYouKill (org.eclipse.jetty.util.thread.strategy)
tryProduce:171,EatWhatYouKill (org.eclipse.jetty.util.thread.strategy)
produce:135,EatWhatYouKill (org.eclipse.jetty.util.thread.strategy)
run:-1,976266910 (org.eclipse.jetty.io.ManagedSelector$$Lambda$1056)
runJob:806,QueuedThreadPool (org.eclipse.jetty.util.thread)
run:938,QueuedThreadPool$Runner (org.eclipse.jetty.util.thread)
run:832,Thread (java.lang)

解决方法

由于这是JSP制作的。

可以使用标准的Servlet错误页面处理。

可以将WEB-INF/web.xml定义为响应状态码405。

  <error-page>
    <error-code>405</error-code>
    <location>/myMethodNotAllowedPath</location>
  </error-page>

您还可以选择定义一个全局错误页面错误处理程序,例如..

  <error-page>
    <location>/myGlobalErrorHandler</location>
  </error-page>

从Servlet 3.0开始,<error-page>可以基于状态码<error-code>,异常<exception-type>或什么都不定义(这意味着所有错误均未被更具体的定义捕获)来定义响应。

Servlet的实现将使用<location>将请求重新分发到已定义的DispatcherType.ERROR,原始请求的详细信息可以在HttpServletRequest.getAttribute(String)值中的各种已定义键/名称下找到。在RequestDispatcher.ERROR_*常量中。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-