001/*
002 * Copyright 2002-2019 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.web.servlet.config.annotation;
018
019import java.util.Collections;
020
021import javax.servlet.ServletContext;
022
023import org.springframework.core.Ordered;
024import org.springframework.lang.Nullable;
025import org.springframework.util.Assert;
026import org.springframework.web.servlet.DispatcherServlet;
027import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
028import org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler;
029
030/**
031 * Configures a request handler for serving static resources by forwarding
032 * the request to the Servlet container's "default" Servlet. This is intended
033 * to be used when the Spring MVC {@link DispatcherServlet} is mapped to "/"
034 * thus overriding the Servlet container's default handling of static resources.
035 *
036 * <p>Since this handler is configured at the lowest precedence, effectively
037 * it allows all other handler mappings to handle the request, and if none
038 * of them do, this handler can forward it to the "default" Servlet.
039 *
040 * @author Rossen Stoyanchev
041 * @author Juergen Hoeller
042 * @since 3.1
043 * @see DefaultServletHttpRequestHandler
044 */
045public class DefaultServletHandlerConfigurer {
046
047        private final ServletContext servletContext;
048
049        @Nullable
050        private DefaultServletHttpRequestHandler handler;
051
052
053        /**
054         * Create a {@link DefaultServletHandlerConfigurer} instance.
055         * @param servletContext the ServletContext to use.
056         */
057        public DefaultServletHandlerConfigurer(ServletContext servletContext) {
058                Assert.notNull(servletContext, "ServletContext is required");
059                this.servletContext = servletContext;
060        }
061
062
063        /**
064         * Enable forwarding to the "default" Servlet.
065         * <p>When this method is used the {@link DefaultServletHttpRequestHandler}
066         * will try to autodetect the "default" Servlet name. Alternatively, you can
067         * specify the name of the default Servlet via {@link #enable(String)}.
068         * @see DefaultServletHttpRequestHandler
069         */
070        public void enable() {
071                enable(null);
072        }
073
074        /**
075         * Enable forwarding to the "default" Servlet identified by the given name.
076         * <p>This is useful when the default Servlet cannot be autodetected,
077         * for example when it has been manually configured.
078         * @see DefaultServletHttpRequestHandler
079         */
080        public void enable(@Nullable String defaultServletName) {
081                this.handler = new DefaultServletHttpRequestHandler();
082                if (defaultServletName != null) {
083                        this.handler.setDefaultServletName(defaultServletName);
084                }
085                this.handler.setServletContext(this.servletContext);
086        }
087
088
089        /**
090         * Return a handler mapping instance ordered at {@link Ordered#LOWEST_PRECEDENCE}
091         * containing the {@link DefaultServletHttpRequestHandler} instance mapped
092         * to {@code "/**"}; or {@code null} if default servlet handling was not
093         * been enabled.
094         * @since 4.3.12
095         */
096        @Nullable
097        protected SimpleUrlHandlerMapping buildHandlerMapping() {
098                if (this.handler == null) {
099                        return null;
100                }
101                return new SimpleUrlHandlerMapping(Collections.singletonMap("/**", this.handler),
102                                Ordered.LOWEST_PRECEDENCE);
103        }
104
105}