为什么 HttpServletResponse 为空?

发布于 2025-01-15 22:59:49 字数 9539 浏览 0 评论 0原文

我最近将我的网页从 2014 年的内容更新为现在的内容。我收到间歇性错误,有时在重新部署后进入登录页面时会出现此错误:

The HttpServletRequest attribute must contain an HttpServletResponse for the attribute javax.servlet.http.HttpServletResponse}]
java.lang.IllegalArgumentException: The HttpServletRequest attribute must contain an HttpServletResponse for the attribute javax.servlet.http.HttpServletResponse
    at org.springframework.security.web.csrf.LazyCsrfTokenRepository.getResponse(LazyCsrfTokenRepository.java:92) ~[spring-security-web-5.3.13.RELEASE.jar:5.3.13.RELEASE]
    at org.springframework.security.web.csrf.LazyCsrfTokenRepository.wrap(LazyCsrfTokenRepository.java:84) ~[spring-security-web-5.3.13.RELEASE.jar:5.3.13.RELEASE]
    at org.springframework.security.web.csrf.LazyCsrfTokenRepository.generateToken(LazyCsrfTokenRepository.java:58) ~[spring-security-web-5.3.13.RELEASE.jar:5.3.13.RELEASE]
    at com.victoreda.playground.controllers.BaseController.getCsrfToken(BaseController.java:317) ~[classes/:?]
    at com.victoreda.playground.controllers.SecurityController.login(SecurityController.java:69) ~[classes/:?]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
    at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.13.jar:5.3.13]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.13.jar:5.3.13]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.13.jar:5.3.13]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.13.jar:5.3.13]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.13.jar:5.3.13]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.13.jar:5.3.13]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067) [spring-webmvc-5.3.13.jar:5.3.13]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) [spring-webmvc-5.3.13.jar:5.3.13]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) [spring-webmvc-5.3.13.jar:5.3.13]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) [spring-webmvc-5.3.13.jar:5.3.13]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) [tomcat9-servlet-api.jar:?]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) [spring-webmvc-5.3.13.jar:5.3.13]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) [tomcat9-servlet-api.jar:?]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) [tomcat9-websocket-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:209) [spring-security-web-5.3.13.RELEASE.jar:5.3.13.RELEASE]
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) [spring-security-web-5.3.13.RELEASE.jar:5.3.13.RELEASE]
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358) [spring-web-5.3.13.jar:5.3.13]
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271) [spring-web-5.3.13.jar:5.3.13]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.filters.ExpiresFilter.doFilter(ExpiresFilter.java:1227) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) [spring-web-5.3.13.jar:5.3.13]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.3.13.jar:5.3.13]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:747) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:688) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367) [tomcat9-coyote-9.0.31.jar:9.0.31]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat9-coyote-9.0.31.jar:9.0.31]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat9-coyote-9.0.31.jar:9.0.31]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1639) [tomcat9-coyote-9.0.31.jar:9.0.31]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat9-coyote-9.0.31.jar:9.0.31]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat9-util-9.0.31.jar:9.0.31]
    at java.lang.Thread.run(Thread.java:829) [?:?]

处理(?)我的登录页面的 java 代码是:

@RequestMapping(value = "/loginpage", method = RequestMethod.GET)
public ModelAndView login(HttpServletRequest request, @RequestParam(value = "error", required = false) String error) {
    final String methodName = "login";
    Helper.logEntrance(getLogger(), methodName);

    ModelAndView result = new ModelAndView(methodName);
    if (error != null) {
        result.addObject("error", "Invalid username or password");
    }
    result.addObject("_csrf", getCsrfToken(request));
    Helper.logExit(getLogger(), methodName, result);
    return result;
}

getCsrfToken 的代码正在

protected CsrfToken getCsrfToken(HttpServletRequest request) {
    // Populate CSRF token since it is not automatically populated by Spring Security
    CsrfToken token = getCsrfTokenRepository().loadToken(request);
    if (token == null) {
        token = getCsrfTokenRepository().generateToken(request);
    }
    getCsrfTokenRepository().saveToken(token, request, null);
    return token;
}

查找在 generateToken 的 Spring 源代码中,我看到错误是在这里引起的

private HttpServletResponse getResponse(HttpServletRequest request) {
    HttpServletResponse response = (HttpServletResponse)request.getAttribute(HTTP_RESPONSE_ATTR);
    if (response == null) {
        throw new IllegalArgumentException("The HttpServletRequest attribute must contain an HttpServletResponse for the attribute " + HTTP_RESPONSE_ATTR);
    } else {
        return response;
    }
}

,因为 response 是(偶尔)null 并且,尽管为此工作大约3天,我不知道为什么。我的感觉是我缺少一些注释或其他东西(因为我已经升级了 .jar 文件)。

I have recently updated my web page from whatever was current in 2014 to whatever is current now. I am getting an intermittent error which occurs sometimes when I got to my login page after redeploying, get this error:

The HttpServletRequest attribute must contain an HttpServletResponse for the attribute javax.servlet.http.HttpServletResponse}]
java.lang.IllegalArgumentException: The HttpServletRequest attribute must contain an HttpServletResponse for the attribute javax.servlet.http.HttpServletResponse
    at org.springframework.security.web.csrf.LazyCsrfTokenRepository.getResponse(LazyCsrfTokenRepository.java:92) ~[spring-security-web-5.3.13.RELEASE.jar:5.3.13.RELEASE]
    at org.springframework.security.web.csrf.LazyCsrfTokenRepository.wrap(LazyCsrfTokenRepository.java:84) ~[spring-security-web-5.3.13.RELEASE.jar:5.3.13.RELEASE]
    at org.springframework.security.web.csrf.LazyCsrfTokenRepository.generateToken(LazyCsrfTokenRepository.java:58) ~[spring-security-web-5.3.13.RELEASE.jar:5.3.13.RELEASE]
    at com.victoreda.playground.controllers.BaseController.getCsrfToken(BaseController.java:317) ~[classes/:?]
    at com.victoreda.playground.controllers.SecurityController.login(SecurityController.java:69) ~[classes/:?]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
    at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.13.jar:5.3.13]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.13.jar:5.3.13]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.13.jar:5.3.13]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.13.jar:5.3.13]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.13.jar:5.3.13]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.13.jar:5.3.13]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067) [spring-webmvc-5.3.13.jar:5.3.13]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) [spring-webmvc-5.3.13.jar:5.3.13]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) [spring-webmvc-5.3.13.jar:5.3.13]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) [spring-webmvc-5.3.13.jar:5.3.13]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) [tomcat9-servlet-api.jar:?]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) [spring-webmvc-5.3.13.jar:5.3.13]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) [tomcat9-servlet-api.jar:?]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) [tomcat9-websocket-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:209) [spring-security-web-5.3.13.RELEASE.jar:5.3.13.RELEASE]
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) [spring-security-web-5.3.13.RELEASE.jar:5.3.13.RELEASE]
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358) [spring-web-5.3.13.jar:5.3.13]
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271) [spring-web-5.3.13.jar:5.3.13]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.filters.ExpiresFilter.doFilter(ExpiresFilter.java:1227) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) [spring-web-5.3.13.jar:5.3.13]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.3.13.jar:5.3.13]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:747) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:688) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat9-catalina-9.0.31.jar:9.0.31]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367) [tomcat9-coyote-9.0.31.jar:9.0.31]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat9-coyote-9.0.31.jar:9.0.31]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat9-coyote-9.0.31.jar:9.0.31]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1639) [tomcat9-coyote-9.0.31.jar:9.0.31]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat9-coyote-9.0.31.jar:9.0.31]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat9-util-9.0.31.jar:9.0.31]
    at java.lang.Thread.run(Thread.java:829) [?:?]

The java code that handles(?) my login page is:

@RequestMapping(value = "/loginpage", method = RequestMethod.GET)
public ModelAndView login(HttpServletRequest request, @RequestParam(value = "error", required = false) String error) {
    final String methodName = "login";
    Helper.logEntrance(getLogger(), methodName);

    ModelAndView result = new ModelAndView(methodName);
    if (error != null) {
        result.addObject("error", "Invalid username or password");
    }
    result.addObject("_csrf", getCsrfToken(request));
    Helper.logExit(getLogger(), methodName, result);
    return result;
}

And the code for getCsrfToken is

protected CsrfToken getCsrfToken(HttpServletRequest request) {
    // Populate CSRF token since it is not automatically populated by Spring Security
    CsrfToken token = getCsrfTokenRepository().loadToken(request);
    if (token == null) {
        token = getCsrfTokenRepository().generateToken(request);
    }
    getCsrfTokenRepository().saveToken(token, request, null);
    return token;
}

Looking at the Spring source code for generateToken I see that the error is caused here

private HttpServletResponse getResponse(HttpServletRequest request) {
    HttpServletResponse response = (HttpServletResponse)request.getAttribute(HTTP_RESPONSE_ATTR);
    if (response == null) {
        throw new IllegalArgumentException("The HttpServletRequest attribute must contain an HttpServletResponse for the attribute " + HTTP_RESPONSE_ATTR);
    } else {
        return response;
    }
}

because response is (occasionally) null and, despite working on this for about 3 days, I have no idea why. My feeling is that I am missing some annotation or something (because I have upgraded the .jar files).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文