【问题标题】:How do you make invalid urls ending in .jsp use the spring 404 page?如何使以 .jsp 结尾的无效 url 使用 spring 404 页面?
【发布时间】:2013-11-22 22:03:59
【问题描述】:

404 页面在我的网站上对所有 url 都正常工作,除非它以 .jsp 结尾。在这种情况下,我得到的是通用的 jboss 404 页面,而不是我的样式化 Spring 404 页面。

我的 web.xml 中有以下内容:

<error-page>
    <error-code>404</error-code>
    <location>/WEB-INF/error/404.jsp</location>
</error-page>

用完整的 web.xml 编辑:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <servlet>
        <servlet-name>mainServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>mainServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring/root-context.xml,
            /WEB-INF/spring-security.xml
        </param-value>
    </context-param>

    <welcome-file-list>
        <welcome-file></welcome-file>
    </welcome-file-list>

    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>
            org.springframework.web.filter.DelegatingFilterProxy
        </filter-class>
    </filter>

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <error-page>
        <error-code>400</error-code>
        <location>/WEB-INF/error/400.jsp</location>
    </error-page>

    <error-page>
        <error-code>403</error-code>
        <location>/WEB-INF/error/403.jsp</location>
    </error-page>

    <error-page>
        <error-code>404</error-code>
        <location>/WEB-INF/error/404.jsp</location>
    </error-page>

    <error-page>
        <error-code>405</error-code>
        <location>/WEB-INF/error/405.jsp</location>
    </error-page>

    <error-page>
        <exception-type>java.lang.Exception</exception-type>
        <location>/WEB-INF/error/error.jsp</location>
    </error-page>

    <context-param>
        <param-name>defaultHtmlEscape</param-name>
        <param-value>true</param-value>
    </context-param>
</web-app>

【问题讨论】:

    标签: spring jsp spring-mvc


    【解决方案1】:

    问题可能是您的 web.xml 直接指向您的 jsp 页面,而不是指向可以指向相应视图的 spring 控制器。

    我很想看看您的 rootContext.xml 以了解您是如何设置视图解析器的。原因可能是 spring 变得混乱...... App Container (JBoss) 只有两种方式最终会处理错误,那就是请求甚至不匹配 Spring 上下文 servlet 或者没有错误生成的错误类型的处理程序(是否有可能尝试处理“asdlfasdf.jsp”最终导致另一种类型的异常没有被记录,然后被扔到 JBoss 并作为 404 处理?)。

    但是你有一些东西可以比较 - 这是我的设置方式:

    我的视图目录中有一个 error.jsp 页面,并设置类似于以下内容的视图解析器:

    <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    

    然后,我有一个基本的 PageController 类,我为所有其他“面向用户”的控制器类扩展了它。该类有一个处理“/error/404”、“/error/403”样式错误页面模式的方法:

    @RequestMapping(value = "/error/{code}")
    public String errorPage(Principal principal, Model model, @PathVariable("code") int code) {
        model.addAttribute("code", code);
        return "error";
    }
    

    然后,我设置了与您类似的 web.xml,仅重定向到 spring 控制器端点以及相应的代码:

    <error-page>
        <error-code>404</error-code>
        <location>/error/404</location>
    </error-page>
    
    <error-page>
        <error-code>403</error-code>
        <location>/error/403</location>
    </error-page>
    

    现在,我不知道这是否是最好的方法,但它对我来说非常有效。 Web 容器将这些错误类型路由到 /error/code 页面,该页面只是调用控制器方法,然后控制器方法生成 error.jsp 页面(通过返回视图名称“error”)。

    由于它将错误代码放入模型中,我有一个处理多种错误类型的 jsp,我只是放置了一个条件,根据错误代码呈现不同的用户消息。换句话说,“页面未找到:(”与“您无权查看此页面!”

    然后我在我的 spring 安全配置中执行此操作,以确保未经身份验证的用户可以看到错误页面(你可能已经有了这部分,因为你可以看到 jsp 页面):

    <http pattern="/error/**" security="none" />
    

    我将它与注释样式的异常处理程序结合起来来完成我所有的服务器异常处理(处理带有 json 错误响应的数据请求和带有 html 错误页面的 html/view 请求),因为您可以只注释一个控制器方法来处理异常或运行时异常。我建议您也检查一下这个方法,因为它非常强大,并且可以非常容易地优雅地记录和处理异常:

    @ExceptionHandler(Exception.class)
    public ModelAndView exceptionHandler(Exception e){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.getModelMap().addAttribute("code", HttpStatus.INTERNAL_SERVER_ERROR);
        modelAndView.setViewName("error");
    
        logger.error("Error handling page request.", e);
        return modelAndView;
    }
    

    这也是确保您有机会记录通过控制器的异常而不必将异常处理放入每个控制器的好方法。

    我创建了两个基类...一个用于我的页面控制器,一个用于我的其余数据控制器。基本页面控制器返回为用户呈现一个漂亮的错误页面的 jsp 视图。基本剩余数据控制器返回带有模型中错误信息的 json 消息,然后 jsp 将打印完整堆栈或仅打印一般错误,具体取决于服务器是在开发模式下运行还是在生产模式下运行。

    【讨论】:

    • 非常感谢,添加错误控制器而不是直接链接到有效的 jsp 页面。
    猜你喜欢
    • 2014-08-11
    • 2019-04-21
    • 1970-01-01
    • 2020-03-08
    • 2017-10-06
    • 2017-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多