zoukankan      html  css  js  c++  java
  • SimpleUrlHandlerMapping的配置

    SimpleUrlHandlerMapping 

    <bean id="loginUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <!-- 第一种方法 -->
        <property name="mappings">
            <props>
                <prop key="/base/login.htm">loginController</prop>
                <prop key="/base/login.htm?method=doLogin">loginController</prop>            
            </props>
        </property>    
        <!-- 第二种方法 -->
        <property name="urlMap">     
            <map>     
                <entry key="/base/login.htm" value-ref="loginController"/>     
            </map>     
        </property>
        <!-- 第三种方法 -->
        <property name="mappings">     
            <bean class="org.springframework.beans.factory.config.PropertiesFactoryBean">     
                <property name="location">     
                    <value>urlMap.properties</value> <!-- 此时urlMap.properties文件应放在WebRoot目录下! -->     
                </property>     
            </bean>     
        </property>    
    </bean>
    <!--第四种-->
    
    <bean id="rechargeNotifyParamResolver" class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
        <property name="mappings">
            <props>
                <prop key="/app/gateway/recharge/ccb/notify.htm">index</prop>
            </props>
        </property>
    </bean>
    <bean id="rechargeNotifyController" class="com.ciispay.site.controller.gateway.RechargeNotifyController" parent="baseController">
        <property name="methodNameResolver">
            <ref bean="rechargeNotifyParamResolver" />
        </property>
          <property name= "rechargeAppService" ref= "rechargeAppService"/>
    </bean>
    
    <!--在父类org.springframework.web.servlet.mvc.multiaction.MultiActionController中有个set方法-->
    public final void setMethodNameResolver(MethodNameResolver methodNameResolver) {
        this.methodNameResolver = methodNameResolver;
    }
     

     SimpleUrlHandlerMapping中的setMappings和setUrlMap方法

    /**
     * Map URL paths to handler bean names.
     * This is the typical way of configuring this HandlerMapping.
     * <p>Supports direct URL matches and Ant-style pattern matches. For syntax
     * details, see the {@link org.springframework.util.AntPathMatcher} javadoc.
     * @param mappings properties with URLs as keys and bean names as values
     * @see #setUrlMap
     */
    public void setMappings(Properties mappings) {
        CollectionUtils.mergePropertiesIntoMap(mappings, this.urlMap);
    }
    /**
     * Set a Map with URL paths as keys and handler beans (or handler bean names)
     * as values. Convenient for population with bean references.
     * <p>Supports direct URL matches and Ant-style pattern matches. For syntax
     * details, see the {@link org.springframework.util.AntPathMatcher} javadoc.
     * @param urlMap map with URLs as keys and beans as values
     * @see #setMappings
     */
    public void setUrlMap(Map<String, ?> urlMap) {
        this.urlMap.putAll(urlMap);
    }

    然后把这些对应的信息注册到Handler,SimpleUrlHandlerMapping就是将请求的url作为key,然后找到对应的Handler。

    initApplicationContext()中registerHandlers()。在registerHandlers()方法中调用父类AbstractUrlHandlerMapping的registerHandler()方法。

    /**
     * Calls the {@link #registerHandlers} method in addition to the
     * superclass's initialization.
     */
    @Override
    public void initApplicationContext() throws BeansException {
        super.initApplicationContext();
        registerHandlers(this.urlMap);
    }
    
    /**
     * Register all handlers specified in the URL map for the corresponding paths.
     * 注册配置在urlMap中的响应路径
     * @param urlMap Map with URL paths as keys and handler beans or bean names as values
     * @throws BeansException if a handler couldn't be registered
     * @throws IllegalStateException if there is a conflicting handler registered
     */
    protected void registerHandlers(Map<String, Object> urlMap) throws BeansException {
        if (urlMap.isEmpty()) {
            logger.warn("Neither 'urlMap' nor 'mappings' set on SimpleUrlHandlerMapping");
        }
        else {
            for (Map.Entry<String, Object> entry : urlMap.entrySet()) {
                String url = entry.getKey();
                Object handler = entry.getValue();
                // Prepend with slash if not already present.
                if (!url.startsWith("/")) {
                    url = "/" + url;
                }
                // Remove whitespace from handler bean name.
                if (handler instanceof String) {
                    handler = ((String) handler).trim();
                }
                registerHandler(url, handler);//调用父类AbstractUrlHandlerMapping中的registerHandler()方法
            }
        }
    }
    
    
    AbstractUrlHandlerMapping
    /** * Register the specified handler for the given URL path. * @param urlPath the URL the bean should be mapped to * @param handler the handler instance or handler bean name String * (a bean name will automatically be resolved into the corresponding handler bean) * @throws BeansException if the handler couldn't be registered * @throws IllegalStateException if there is a conflicting handler registered */ protected void registerHandler(String urlPath, Object handler) throws BeansException, IllegalStateException { Assert.notNull(urlPath, "URL path must not be null"); Assert.notNull(handler, "Handler object must not be null"); Object resolvedHandler = handler; // Eagerly resolve handler if referencing singleton via name. if (!this.lazyInitHandlers && handler instanceof String) { String handlerName = (String) handler; if (getApplicationContext().isSingleton(handlerName)) { resolvedHandler = getApplicationContext().getBean(handlerName); } } Object mappedHandler = this.handlerMap.get(urlPath); if (mappedHandler != null) { if (mappedHandler != resolvedHandler) { throw new IllegalStateException( "Cannot map " + getHandlerDescription(handler) + " to URL path [" + urlPath + "]: There is already " + getHandlerDescription(mappedHandler) + " mapped."); } } else { if (urlPath.equals("/")) { if (logger.isInfoEnabled()) { logger.info("Root mapping to " + getHandlerDescription(handler)); } setRootHandler(resolvedHandler); } else if (urlPath.equals("/*")) { if (logger.isInfoEnabled()) { logger.info("Default mapping to " + getHandlerDescription(handler)); } setDefaultHandler(resolvedHandler); } else { this.handlerMap.put(urlPath, resolvedHandler); if (logger.isInfoEnabled()) { logger.info("Mapped URL path [" + urlPath + "] onto " + getHandlerDescription(handler)); } } } }

    然后看下Spring是如何取出来的

    在DispatcherServlet中的doDispatch()方法中
    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
      ...
      mappedHandler = getHandler(processedRequest, false);
      ...
    }
    
    /**
     * Return the HandlerExecutionChain for this request. Try all handler mappings in order.
     * @param request current HTTP request
     * @param cache whether to cache the HandlerExecutionChain in a request attribute
     * @return the HandlerExecutionChain, or {@code null} if no handler could be found
     * @deprecated as of Spring 3.0.4, in favor of {@link #getHandler(javax.servlet.http.HttpServletRequest)},
     * with this method's cache attribute now effectively getting ignored
     */
    @Deprecated
    protected HandlerExecutionChain getHandler(HttpServletRequest request, boolean cache) throws Exception {
        return getHandler(request);
    }
    
    /**
     * Return the HandlerExecutionChain for this request.
     * <p>Tries all handler mappings in order.
     * @param request current HTTP request
     * @return the HandlerExecutionChain, or {@code null} if no handler could be found
     */
    protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
        for (HandlerMapping hm : this.handlerMappings) {
            if (logger.isTraceEnabled()) {
                logger.trace(
                        "Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");
            }
            HandlerExecutionChain handler = hm.getHandler(request);
            if (handler != null) {
                return handler;
            }
        }
        return null;
    }
    我们主要看: HandlerExecutionChain handler
    = hm.getHandler(request); public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { Object handler = getHandlerInternal(request); if (handler == null) { handler = getDefaultHandler(); } if (handler == null) { return null; } // Bean name or resolved handler? if (handler instanceof String) { String handlerName = (String) handler; handler = getApplicationContext().getBean(handlerName); } return getHandlerExecutionChain(handler, request); } AbstractHandlerMethodMapping<T> extends AbstractHandlerMapping,并且在AbstractHandlerMethodMapping中重写了AbstractHandlerMapping中的getHandlerInternal方法 方法:
    @Override
    protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception { String lookupPath = getUrlPathHelper().getLookupPathForRequest(request); if (logger.isDebugEnabled()) { logger.debug("Looking up handler method for path " + lookupPath); } HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request); if (logger.isDebugEnabled()) { if (handlerMethod != null) { logger.debug("Returning handler method [" + handlerMethod + "]"); } else { logger.debug("Did not find handler method for [" + lookupPath + "]"); } } return (handlerMethod != null) ? handlerMethod.createWithResolvedBean() : null; } 再看下lookupHandlerMethod()方法 protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception { List<Match> matches = new ArrayList<Match>(); List<T> directPathMatches = this.urlMap.get(lookupPath); if (directPathMatches != null) { addMatchingMappings(directPathMatches, matches, request); } if (matches.isEmpty()) { // No choice but to go through all mappings addMatchingMappings(this.handlerMethods.keySet(), matches, request); } if (!matches.isEmpty()) { Comparator<Match> comparator = new MatchComparator(getMappingComparator(request)); Collections.sort(matches, comparator); if (logger.isTraceEnabled()) { logger.trace("Found " + matches.size() + " matching mapping(s) for [" + lookupPath + "] : " + matches); } Match bestMatch = matches.get(0); if (matches.size() > 1) { Match secondBestMatch = matches.get(1); if (comparator.compare(bestMatch, secondBestMatch) == 0) { Method m1 = bestMatch.handlerMethod.getMethod(); Method m2 = secondBestMatch.handlerMethod.getMethod(); throw new IllegalStateException( "Ambiguous handler methods mapped for HTTP path '" + request.getRequestURL() + "': {" + m1 + ", " + m2 + "}"); } } handleMatch(bestMatch.mapping, lookupPath, request); return bestMatch.handlerMethod; } else { return handleNoMatch(handlerMethods.keySet(), lookupPath, request); } }
  • 相关阅读:
    如何有效的写算法题的几个小tips
    题目
    记录加入博客园,申请开通cnblog
    关于套接字socket程序参数设置
    int main (int argc, const char * argv[0])及指针数组与数组指针
    sleep函数
    signal函数
    C htonl()函数
    位域unsigned char a:4
    关于TCP和UDP的一个理解
  • 原文地址:https://www.cnblogs.com/lemon-now/p/5553510.html
Copyright © 2011-2022 走看看