001/*
002 * Copyright 2002-2017 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;
020import javax.servlet.ServletContext;
021
022import org.springframework.util.Assert;
023import org.springframework.web.servlet.DispatcherServlet;
024import org.springframework.web.servlet.handler.AbstractHandlerMapping;
025import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
026import org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler;
027
028/**
029 * Configures a request handler for serving static resources by forwarding
030 * the request to the Servlet container's "default" Servlet. This is intended
031 * to be used when the Spring MVC {@link DispatcherServlet} is mapped to "/"
032 * thus overriding the Servlet container's default handling of static resources.
033 *
034 * <p>Since this handler is configured at the lowest precedence, effectively
035 * it allows all other handler mappings to handle the request, and if none
036 * of them do, this handler can forward it to the "default" Servlet.
037 *
038 * @author Rossen Stoyanchev
039 * @author Juergen Hoeller
040 * @since 3.1
041 * @see DefaultServletHttpRequestHandler
042 */
043public class DefaultServletHandlerConfigurer {
044
045        private final ServletContext servletContext;
046
047        private DefaultServletHttpRequestHandler handler;
048
049
050        /**
051         * Create a {@link DefaultServletHandlerConfigurer} instance.
052         * @param servletContext the ServletContext to use.
053         */
054        public DefaultServletHandlerConfigurer(ServletContext servletContext) {
055                Assert.notNull(servletContext, "ServletContext is required");
056                this.servletContext = servletContext;
057        }
058
059
060        /**
061         * Enable forwarding to the "default" Servlet.
062         * <p>When this method is used the {@link DefaultServletHttpRequestHandler}
063         * will try to autodetect the "default" Servlet name. Alternatively, you can
064         * specify the name of the default Servlet via {@link #enable(String)}.
065         * @see DefaultServletHttpRequestHandler
066         */
067        public void enable() {
068                enable(null);
069        }
070
071        /**
072         * Enable forwarding to the "default" Servlet identified by the given name.
073         * <p>This is useful when the default Servlet cannot be autodetected,
074         * for example when it has been manually configured.
075         * @see DefaultServletHttpRequestHandler
076         */
077        public void enable(String defaultServletName) {
078                this.handler = new DefaultServletHttpRequestHandler();
079                this.handler.setDefaultServletName(defaultServletName);
080                this.handler.setServletContext(this.servletContext);
081        }
082
083
084        /**
085         * Return a handler mapping instance ordered at {@link Integer#MAX_VALUE} containing the
086         * {@link DefaultServletHttpRequestHandler} instance mapped to {@code "/**"};
087         * or {@code null} if default servlet handling was not been enabled.
088         * @since 4.3.12
089         */
090        protected SimpleUrlHandlerMapping buildHandlerMapping() {
091                if (this.handler == null) {
092                        return null;
093                }
094
095                SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping();
096                handlerMapping.setUrlMap(Collections.singletonMap("/**", this.handler));
097                handlerMapping.setOrder(Integer.MAX_VALUE);
098                return handlerMapping;
099        }
100
101        /**
102         * @deprecated as of 4.3.12, in favor of {@link #buildHandlerMapping()}
103         */
104        @Deprecated
105        protected AbstractHandlerMapping getHandlerMapping() {
106                return buildHandlerMapping();
107        }
108
109}