001/* 002 * Copyright 2002-2015 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.handler; 018 019import java.util.LinkedHashMap; 020import java.util.Map; 021import java.util.Properties; 022 023import org.springframework.beans.BeansException; 024import org.springframework.util.CollectionUtils; 025 026/** 027 * Implementation of the {@link org.springframework.web.servlet.HandlerMapping} 028 * interface to map from URLs to request handler beans. Supports both mapping to bean 029 * instances and mapping to bean names; the latter is required for non-singleton handlers. 030 * 031 * <p>The "urlMap" property is suitable for populating the handler map with 032 * bean references, e.g. via the map element in XML bean definitions. 033 * 034 * <p>Mappings to bean names can be set via the "mappings" property, in a form 035 * accepted by the {@code java.util.Properties} class, like as follows:<br> 036 * {@code 037 * /welcome.html=ticketController 038 * /show.html=ticketController 039 * }<br> 040 * The syntax is {@code PATH=HANDLER_BEAN_NAME}. 041 * If the path doesn't begin with a slash, one is prepended. 042 * 043 * <p>Supports direct matches (given "/test" -> registered "/test") and "*" 044 * pattern matches (given "/test" -> registered "/t*"). Note that the default 045 * is to map within the current servlet mapping if applicable; see the 046 * {@link #setAlwaysUseFullPath "alwaysUseFullPath"} property. For details on the 047 * pattern options, see the {@link org.springframework.util.AntPathMatcher} javadoc. 048 049 * @author Rod Johnson 050 * @author Juergen Hoeller 051 * @see #setMappings 052 * @see #setUrlMap 053 * @see BeanNameUrlHandlerMapping 054 */ 055public class SimpleUrlHandlerMapping extends AbstractUrlHandlerMapping { 056 057 private final Map<String, Object> urlMap = new LinkedHashMap<String, Object>(); 058 059 060 /** 061 * Map URL paths to handler bean names. 062 * This is the typical way of configuring this HandlerMapping. 063 * <p>Supports direct URL matches and Ant-style pattern matches. For syntax 064 * details, see the {@link org.springframework.util.AntPathMatcher} javadoc. 065 * @param mappings properties with URLs as keys and bean names as values 066 * @see #setUrlMap 067 */ 068 public void setMappings(Properties mappings) { 069 CollectionUtils.mergePropertiesIntoMap(mappings, this.urlMap); 070 } 071 072 /** 073 * Set a Map with URL paths as keys and handler beans (or handler bean names) 074 * as values. Convenient for population with bean references. 075 * <p>Supports direct URL matches and Ant-style pattern matches. For syntax 076 * details, see the {@link org.springframework.util.AntPathMatcher} javadoc. 077 * @param urlMap map with URLs as keys and beans as values 078 * @see #setMappings 079 */ 080 public void setUrlMap(Map<String, ?> urlMap) { 081 this.urlMap.putAll(urlMap); 082 } 083 084 /** 085 * Allow Map access to the URL path mappings, with the option to add or 086 * override specific entries. 087 * <p>Useful for specifying entries directly, for example via "urlMap[myKey]". 088 * This is particularly useful for adding or overriding entries in child 089 * bean definitions. 090 */ 091 public Map<String, ?> getUrlMap() { 092 return this.urlMap; 093 } 094 095 096 /** 097 * Calls the {@link #registerHandlers} method in addition to the 098 * superclass's initialization. 099 */ 100 @Override 101 public void initApplicationContext() throws BeansException { 102 super.initApplicationContext(); 103 registerHandlers(this.urlMap); 104 } 105 106 /** 107 * Register all handlers specified in the URL map for the corresponding paths. 108 * @param urlMap Map with URL paths as keys and handler beans or bean names as values 109 * @throws BeansException if a handler couldn't be registered 110 * @throws IllegalStateException if there is a conflicting handler registered 111 */ 112 protected void registerHandlers(Map<String, Object> urlMap) throws BeansException { 113 if (urlMap.isEmpty()) { 114 logger.warn("Neither 'urlMap' nor 'mappings' set on SimpleUrlHandlerMapping"); 115 } 116 else { 117 for (Map.Entry<String, Object> entry : urlMap.entrySet()) { 118 String url = entry.getKey(); 119 Object handler = entry.getValue(); 120 // Prepend with slash if not already present. 121 if (!url.startsWith("/")) { 122 url = "/" + url; 123 } 124 // Remove whitespace from handler bean name. 125 if (handler instanceof String) { 126 handler = ((String) handler).trim(); 127 } 128 registerHandler(url, handler); 129 } 130 } 131 } 132 133}