【问题标题】:How to define <welcome-file-list> and <error-page> in servlet 3.0's web.xml-less?如何在 servlet 3.0 的 web.xml-less 中定义 <welcome-file-list> 和 <error-page>?
【发布时间】:2012-11-07 03:40:32
【问题描述】:

我有现有的 web 应用程序,我想将其转换为 servlet 3.0 的 web.xml-less。我已经设法让它工作了,但是 web.xml 中有 2 个标签,我仍然不知道 web.xml-less 环境中的等效代码。

<welcome-file-list>
    <welcome-file>/index.jsp</welcome-file>
</welcome-file-list>

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

感谢任何帮助

【问题讨论】:

    标签: java tomcat7 java-ee-6 servlet-3.0


    【解决方案1】:

    在 Spring Boot 2.0 中您可以使用此代码

    @Configuration
    public class TomcatInitializer implements 
        WebServerFactoryCustomizer<TomcatServletWebServerFactory> , TomcatContextCustomizer {
        @Override
        public void customize(TomcatServletWebServerFactory factory) {
            factory.addContextCustomizers(this);
        }
    
        private ErrorPage createStatusErrorPage(int errorCode, String location) {
            ErrorPage errorPage = new ErrorPage();
            errorPage.setErrorCode(errorCode);
            errorPage.setLocation(location);
            return errorPage;
        }
    
        private ErrorPage createExceptionErrorPage(Class<?> klass, String location) {
            ErrorPage errorPage = new ErrorPage();
            errorPage.setExceptionType(klass);
            errorPage.setLocation(location);
            return errorPage;
        }
    
        @Override
        public void customize(Context context) {
            context.addWelcomeFile("/index.jsp");
            context.addErrorPage(createStatusErrorPage(404, "/404.jsp"));
            context.addErrorPage(createExeptionErrorPage(Exception.class, "exception.jsp"));
            context.setSessionTimeout(120);
        }
    }     
        
    

    【讨论】:

      【解决方案2】:

      在 Spring Boot 或一般 Spring MVC 应用程序中用于以下场景:

      可以从使用自定义 ResourceHandlerRegistry 注册的位置提供静态文件。我们有一个静态资源 index.html,它可以在 localhost:8080/index.html 访问。我们只想将 localhost:8080/ 请求重定向到 localhost:8080/index.html,可以使用以下代码。

      package in.geekmj.config;
      
      import org.springframework.context.annotation.Configuration;
      
      import org.springframework.web.servlet.config.annotation.EnableWebMvc;
      
      import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
      
      import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
      
      import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
      
      @Configuration
      @EnableWebMvc
      public class WebConfiguration extends WebMvcConfigurerAdapter {
      
      private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
              "classpath:/resources/", "classpath:/static/", "classpath:/public/" };
      
      @Override
      public void addResourceHandlers(ResourceHandlerRegistry registry) {
          registry.addResourceHandler("/**").addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS);
      }
      
      @Override
      public void addViewControllers(ViewControllerRegistry registry) {
          registry.addRedirectViewController("/", "/index.html");
      }
      }
      

      现在访问 localhost:8080/ 将重定向到 localhost:8080/index.html

      【讨论】:

        【解决方案3】:

        对于模拟欢迎页面列表,将其放入

        @EnableWebMvc
        @Configuration
        @ComponentScan("com.springapp.mvc")
        public class MvcConfig extends WebMvcConfigurerAdapter {
        ...
            @Override
            public void addResourceHandlers(ResourceHandlerRegistry registry) {
                registry.addResourceHandler("/*.html").addResourceLocations("/WEB-INF/pages/");
            }
        
            @Override
            public void addViewControllers(ViewControllerRegistry registry) {
                registry.addViewController("/").setViewName("forward:/index.html");
            }
        ...
        }
        

        【讨论】:

        • 如果有用,使用 HTTP 301 而不是 302 代码重定向到 /index.html,您可以使用以下代码:registry.addViewController("/").setStatusCode(HttpStatus.MOVED_PERMANENTLY).setViewName("forward:/index.html");
        【解决方案4】:

        在 Servlets 3.0 中,很多情况下您不需要 web.xml,但是,有时它是必需的或只是有用的。您的案例只是其中之一 - 没有特殊的注释来定义欢迎文件列表或错误页面。

        另一件事是 - 您真的希望对它们进行硬编码吗?对于基于注释/编程的配置和 XML 中的声明性配置,有一些有效的用例。迁移到 Servlets 3.0 并不一定意味着不惜一切代价摆脱 web.xml。

        我会发现您发布的条目是一个更好的 XML 配置示例。首先 - 它们可以从部署更改为部署,其次 - 它们影响整个应用程序,而不是任何特定的 Servlet。

        【讨论】:

        • 你说得对,只要 web.xml 使用 3.0 版本,容器就会同时加载 web.xml 和 webservlet 引导程序。
        • 没错。请注意您使用的版本和 metadata-complete 属性(错误或不存在)。定义您正在使用的最新版本总是好的;我为最常用的描述符准备了一些空的 XML 文件并发布了它们here。您可能会发现它很有用。
        • 不要将其视为“硬编码”,而是“编码良好”。 JavaConfig 可以很好地用于类型安全和其他blog.codecentric.de/en/2012/07/… 当然,您不必为无 xml 配置迁移所有内容,但如果您开始一个项目,这可能是一个不错的决定。当所有 javaweb 开始时,请记住:您的 java 程序员越高级,您“编码”的 xml 就越多。它让我颤抖。 :)
        • @Moesio,在这种情况下,它仍然是硬编码的。如果您考虑采用相同的应用程序并在不同的环境中部署,那么打开/编辑web.xml 比重新编译代码要容易得多。尽管如此,我知道 JavaConfiguration 带来的附加值——我只是没有看到它用于 OP 案例。最后,我们谈论的是没有 Spring 的 Java EE 6,因此没有 Spring Java-bean 容器配置。
        • 有时我想知道为什么我们要回到程序化的配置方式。难道我们一开始就没有理由以声明方式配置事物,这就是我们发明它的原因吗?
        猜你喜欢
        • 2011-02-02
        • 2016-11-28
        • 1970-01-01
        • 2017-04-20
        • 1970-01-01
        • 2014-12-02
        • 2017-11-11
        • 2017-08-19
        相关资源
        最近更新 更多