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.ArrayList; 020import java.util.LinkedHashMap; 021import java.util.List; 022import java.util.Map; 023 024import org.springframework.context.ApplicationContext; 025import org.springframework.http.HttpStatus; 026import org.springframework.web.servlet.handler.AbstractHandlerMapping; 027import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping; 028 029/** 030 * Assists with the registration of simple automated controllers pre-configured 031 * with status code and/or a view. 032 * 033 * @author Rossen Stoyanchev 034 * @author Keith Donald 035 * @since 3.1 036 */ 037public class ViewControllerRegistry { 038 039 private ApplicationContext applicationContext; 040 041 private final List<ViewControllerRegistration> registrations = new ArrayList<ViewControllerRegistration>(4); 042 043 private final List<RedirectViewControllerRegistration> redirectRegistrations = 044 new ArrayList<RedirectViewControllerRegistration>(10); 045 046 private int order = 1; 047 048 049 /** 050 * Class constructor with {@link ApplicationContext}. 051 * @since 4.3.12 052 */ 053 public ViewControllerRegistry(ApplicationContext applicationContext) { 054 this.applicationContext = applicationContext; 055 } 056 057 @Deprecated 058 public ViewControllerRegistry() { 059 } 060 061 062 /** 063 * Map a view controller to the given URL path (or pattern) in order to render 064 * a response with a pre-configured status code and view. 065 * <p>Patterns like {@code "/admin/**"} or {@code "/articles/{articlename:\\w+}"} 066 * are allowed. See {@link org.springframework.util.AntPathMatcher} for more details on the 067 * syntax. 068 */ 069 public ViewControllerRegistration addViewController(String urlPath) { 070 ViewControllerRegistration registration = new ViewControllerRegistration(urlPath); 071 registration.setApplicationContext(this.applicationContext); 072 this.registrations.add(registration); 073 return registration; 074 } 075 076 /** 077 * Map a view controller to the given URL path (or pattern) in order to redirect 078 * to another URL. By default the redirect URL is expected to be relative to 079 * the current ServletContext, i.e. as relative to the web application root. 080 * @since 4.1 081 */ 082 public RedirectViewControllerRegistration addRedirectViewController(String urlPath, String redirectUrl) { 083 RedirectViewControllerRegistration registration = new RedirectViewControllerRegistration(urlPath, redirectUrl); 084 registration.setApplicationContext(this.applicationContext); 085 this.redirectRegistrations.add(registration); 086 return registration; 087 } 088 089 /** 090 * Map a simple controller to the given URL path (or pattern) in order to 091 * set the response status to the given code without rendering a body. 092 * @since 4.1 093 */ 094 public void addStatusController(String urlPath, HttpStatus statusCode) { 095 ViewControllerRegistration registration = new ViewControllerRegistration(urlPath); 096 registration.setApplicationContext(this.applicationContext); 097 registration.setStatusCode(statusCode); 098 registration.getViewController().setStatusOnly(true); 099 this.registrations.add(registration); 100 } 101 102 /** 103 * Specify the order to use for the {@code HandlerMapping} used to map view 104 * controllers relative to other handler mappings configured in Spring MVC. 105 * <p>By default this is set to 1, i.e. right after annotated controllers, 106 * which are ordered at 0. 107 */ 108 public void setOrder(int order) { 109 this.order = order; 110 } 111 112 113 /** 114 * Return the {@code HandlerMapping} that contains the registered view 115 * controller mappings, or {@code null} for no registrations. 116 * @since 4.3.12 117 */ 118 protected SimpleUrlHandlerMapping buildHandlerMapping() { 119 if (this.registrations.isEmpty() && this.redirectRegistrations.isEmpty()) { 120 return null; 121 } 122 123 Map<String, Object> urlMap = new LinkedHashMap<String, Object>(); 124 for (ViewControllerRegistration registration : this.registrations) { 125 urlMap.put(registration.getUrlPath(), registration.getViewController()); 126 } 127 for (RedirectViewControllerRegistration registration : this.redirectRegistrations) { 128 urlMap.put(registration.getUrlPath(), registration.getViewController()); 129 } 130 131 SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping(); 132 handlerMapping.setUrlMap(urlMap); 133 handlerMapping.setOrder(this.order); 134 return handlerMapping; 135 } 136 137 /** 138 * @deprecated as of 4.3.12, in favor of {@link #buildHandlerMapping()} 139 */ 140 @Deprecated 141 protected AbstractHandlerMapping getHandlerMapping() { 142 return buildHandlerMapping(); 143 } 144 145 @Deprecated 146 protected void setApplicationContext(ApplicationContext applicationContext) { 147 this.applicationContext = applicationContext; 148 } 149 150}