如何在 servlet 3.0 的 web.xml-less 中定义 <welcome-file-list> 和 <error-page>?

Posted

技术标签:

【中文标题】如何在 servlet 3.0 的 web.xml-less 中定义 <welcome-file-list> 和 <error-page>?【英文标题】:How to define <welcome-file-list> and <error-page> in servlet 3.0's web.xml-less? 【发布时间】: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>

感谢任何帮助

【问题讨论】:

【参考方案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 容器配置。 有时我想知道为什么我们要回到程序化的配置方式。难道我们一开始就没有理由以声明方式配置事物,这就是我们发明它的原因吗?

以上是关于如何在 servlet 3.0 的 web.xml-less 中定义 <welcome-file-list> 和 <error-page>?的主要内容,如果未能解决你的问题,请参考以下文章

XML配置Servlet Servlet是3.0版本以下的版本

不同版本(2.3,2.4,2.5,3.0)的Servlet web.xml 头信息

web.xml & web-fragment.xml (Servlet 2.3, 2.4, 2.5 + 3.0)模板

File Templates for web.xml & web-fragment.xml (Servlet 2.3, 2.4, 2.5 + 3.0)

Java Servlet 2.3/2.4/2.5/3.0/3.1/4.0 各web.xml文件

Java 之 Servlet 3.0