
org.tinygroup.springmvc.handlermapping.DefaultCOCUrlHandlerMapping Maven / Gradle / Ivy
The newest version!
/**
* Copyright (c) 1997-2013, www.tinygroup.org ([email protected]).
*
* Licensed under the GPL, Version 3.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.gnu.org/licenses/gpl.html
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.tinygroup.springmvc.handlermapping;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping;
import org.tinygroup.springmvc.coc.ConventionHelper;
import org.tinygroup.springmvc.util.WebUtil;
import org.tinygroup.weblayer.WebContext;
import org.tinygroup.weblayer.mvc.WebContextAware;
import org.tinygroup.weblayer.webcontext.util.WebContextUtil;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
/**
*
* @author kevin.luy
* @since 2014年7月19日
*/
public class DefaultCOCUrlHandlerMapping extends
DefaultAnnotationHandlerMapping {
private static final Log logger = LogFactory
.getLog(DefaultCOCUrlHandlerMapping.class);
private ConventionHelper conventionHelper;
public void setConventionHelper(ConventionHelper conventionHelper) {
this.conventionHelper = conventionHelper;
}
@Override
protected String[] determineUrlsForHandler(String beanName) {
String[] urls = super.determineUrlsForHandler(beanName);
try {
// 沒有requestMapping
Object obj = getApplicationContext().getBean(beanName);
if (urls == null && conventionHelper.isHandler(obj)) {
// desicide url
urls = conventionHelper.determineUrl(obj);
}
} catch (Exception e) {
if (logger.isWarnEnabled()) {
logger.warn("resolve the uris mapping for handler err!", e);
}
}
return urls;
}
protected Object lookupHandler(String urlPath, HttpServletRequest request)
throws Exception {
// 处理约定系列时,如果有后缀,需要忽略
// Direct match?
Object handler = getHandlerMap().get(urlPath);
if (handler != null) {
// Bean name or resolved handler?
if (handler instanceof String) {
String handlerName = (String) handler;
handler = getApplicationContext().getBean(handlerName);
}
validateHandler(handler, request);
return buildPathExposingHandler(handler, urlPath, urlPath, null);
}
// +++ convention match 去除后缀,如果可以直接match上
String noExtPath = WebUtil.getUriWithoutExtension(urlPath);
boolean hasExtension = !StringUtils.equals(urlPath, noExtPath);
// for Pattern match?
List matchingPatterns = new ArrayList();
if (hasExtension) {
// 去掉后缀再尝试下
handler = getHandlerMap().get(noExtPath);
if (handler != null) {
// Bean name or resolved handler?
if (handler instanceof String) {
String handlerName = (String) handler;
handler = getApplicationContext().getBean(handlerName);
}
if (logger.isDebugEnabled()) {
logger.debug("Convention Matching for request [" + urlPath
+ "] are " + noExtPath);
}
validateHandler(handler, request);
return buildPathExposingHandler(handler, urlPath, urlPath, null);
}
// pattern match
for (String registeredPattern : getHandlerMap().keySet()) {
if (getPathMatcher().match(registeredPattern, urlPath)) {
// 如果是约定开发的,那么容易把 users/1.htm match为
// users/{id},需要进一步处理,否则直接匹配返回。
if (!conventionHelper.isConventional(registeredPattern)) {
matchingPatterns.add(registeredPattern);
continue;
}
}
// 解决condition: convention && request path has extension
if ((hasExtension && getPathMatcher().match(registeredPattern,
noExtPath))) {
// if request path has extension ,then add the extension to
// pattern
matchingPatterns.add(registeredPattern);
}
}
} else {// 无后缀情况
// pattern match
for (String registeredPattern : getHandlerMap().keySet()) {
if (getPathMatcher().match(registeredPattern, urlPath)) {
matchingPatterns.add(registeredPattern);
}
}
}
String bestPatternMatch = null;
Comparator patternComparator = getPathMatcher()
.getPatternComparator(urlPath);
if (!matchingPatterns.isEmpty()) {
Collections.sort(matchingPatterns, patternComparator);
if (logger.isDebugEnabled()) {
logger.debug("Matching patterns for request [" + urlPath
+ "] are " + matchingPatterns);
}
bestPatternMatch = matchingPatterns.get(0);
}
if (bestPatternMatch != null) {
handler = getHandlerMap().get(bestPatternMatch);
// Bean name or resolved handler?
if (handler instanceof String) {
String handlerName = (String) handler;
handler = getApplicationContext().getBean(handlerName);
}
validateHandler(handler, request);
if (conventionHelper.isConventional(bestPatternMatch)
&& hasExtension) {
urlPath = noExtPath;
}
String pathWithinMapping = getPathMatcher()
.extractPathWithinPattern(bestPatternMatch, urlPath);
// There might be multiple 'best patterns', let's make sure we have
// the correct URI template variables
// for all of them
Map uriTemplateVariables = new LinkedHashMap();
for (String matchingPattern : matchingPatterns) {
if (patternComparator
.compare(bestPatternMatch, matchingPattern) == 0) {
uriTemplateVariables.putAll(getPathMatcher()
.extractUriTemplateVariables(matchingPattern,
urlPath));
}
}
if (logger.isDebugEnabled()) {
logger.debug("URI Template variables for request [" + urlPath
+ "] are " + uriTemplateVariables);
}
return buildPathExposingHandler(handler, bestPatternMatch,
pathWithinMapping, uriTemplateVariables);
}
// No handler found...
return null;
}
/**
* Validate the given annotated handler against the current request.
* 如果handler实现WebContextAware接口,那么就注入请求上下文
*
* @see #validateMapping
*/
@Override
protected void validateHandler(Object handler, HttpServletRequest request)
throws Exception {
super.validateHandler(handler, request);
if (handler instanceof WebContextAware) {
WebContext webContext = WebContextUtil.getWebContext(request);
WebContextAware webContextAware = (WebContextAware) handler;
webContextAware.setContext(webContext);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy