31

I have existing web-app which I want to convert into web.xml-less of servlet's 3.0. I've managed to make it working, however there are 2 tags in web.xml which I still don't know the equivalent code in web.xml-less environment.

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

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

Any help is appreciated

Wins
  • 3,420
  • 4
  • 36
  • 70

4 Answers4

31

In Servlets 3.0 you don't need a web.xml for many cases, however, sometimes it's required or just useful. Your case is just one of them - there is no special annotations to define welcome-file list or error-pages.

Another thing is - would you really like to have them hardcoded? There are some valid use-cases for annotation / programmatic based configuration and for declarative configuration in XML. Moving to Servlets 3.0 doesn't necessarily means getting rid of web.xml at all cost.

I would find the entries you posted a better example of configuration in XML. Firstly - they can be changed from deployment to deployment and secondly - they affect whole application and not any particular Servlet.

Piotr Nowicki
  • 17,914
  • 8
  • 63
  • 82
  • 1
    You're right, as long as the web.xml uses version 3.0, the container will load both web.xml and webservlet bootstrapper. – Wins Nov 30 '12 at 01:21
  • 3
    Exactly. Just mind the version you use and the metadata-complete attribute (either false or absent). It's always good to define the most current version you're using; I've prepared some empty XML files for most commonly used descriptors and published them [here](http://piotrnowicki.com/2012/11/sample-empty-java-ee-6-files/). You might find it useful. – Piotr Nowicki Nov 30 '12 at 08:18
  • 1
    Don't consider it as 'hard coded', but 'well coded'. JavaConfig can be nice for type safing and others https://blog.codecentric.de/en/2012/07/spring-dependency-injection-styles-why-i-love-java-based-configuration/ Sure, you are not forced to migrate all for no-xml configuration, but if you starting a project, it can be a good decision. That's make remeber when all javaweb begins: The more senior java programmer you are, the more xml you 'code'. It makes me shiver. :) – Moesio May 03 '14 at 02:15
  • @Moesio, it's still hard coded for me in this case. If you consider taking the same application and deploying in different environment, then opening/editing `web.xml` is much easier than recompiling of your code. Nevertheless, I know the added value that JavaConfiguration comes with - I just don't see it for the OP case. Finally, we're talking about Java EE 6 without Spring, so without Spring Java-bean container configuration. – Piotr Nowicki May 04 '14 at 09:18
  • 1
    Sometimes I wonder why are we going back to programmatic way of configuring things. Didn't we have reasons for declarative way of configuring things in the first place which are why we invented it? – supertonsky Jan 25 '18 at 11:05
10

For analog welcome-page-list put this in

@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");
    }
...
}
  • 1
    In case it's of use, to redirect to /index.html using a HTTP 301 instead of 302 code you can use the following code: `registry.addViewController("/").setStatusCode(HttpStatus.MOVED_PERMANENTLY).setViewName("forward:/index.html");` – gar Sep 18 '15 at 16:19
2

In Spring Boot or general Spring MVC app for following scenario:

Static files can be served from locations registered with a custom ResourceHandlerRegistry. We have a static resource index.html and it can accessed at localhost:8080/index.html. We want to just redirect localhost:8080/ request to localhost:8080/index.html, following code will can be used.

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");
}
}

Now accessing localhost:8080/ will redirect to localhost:8080/index.html

Mrityunjay
  • 33
  • 1
  • 8
0

In Spring Boot 2.0 you can use this code

@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);
    }
}