SpringMVC source code, springmvc source code

Source: Internet
Author: User

SpringMVC source code, springmvc source code

AbstractHandlerMethodMapping interface getHandlerInternal to define the search process

RequestMappingInfoHandlerMapping: Based on RequestMappingInfo, the matching conditions are refined. If no matching condition is found, the matching conditions are repeatedly tried using RequestCondition.

Although RequestMappingHandlerMapping is a beneficiary, nothing is done here (that is, during initialization, generate RequestMappingInfo according to @ Controller, @ RequestMapping annotation; and determine whether the target Handler implements isHandler based on the two annotations)

 

AbstractHandlerMethodMapping implementation interface getHandlerInternal

1. Use UrlPathHelper to find the path corresponding to the request

2. Find the HandlerMethod corresponding to the path.

2.1 search for the matching condition RequestMappingInfo from urlMap

2.2 If the equivalence value finds a matching condition, add it to the match condition.

2.3 if no matching condition is found, use RequestMappingInfo of all handlermethods for matching

2.4 sort the matched matches, obtain the Match with the highest priority, and check whether it is the only Match with the highest priority.

2.5 encapsulate the two conditions that match the condition but do not match the condition.

3. encapsulate HandlerMethod to ensure that the bean stores instances.

 

// AbstractHandlerMethodMapping

Implementation interface getHandlerInternal

1 package org. springframework. web. servlet. handler 2 // your acthandlermethodmapping <T> 3/** 4 * Look up a handler method for the given request. 5 */6 @ Override 7 protected HandlerMethod getHandlerInternal (HttpServletRequest request) throws Exception {8 // It is the url 9 String lookupPath = getUrlPathHelper () corresponding to the request (). getLookupPathForRequest (request); 10 // find the processor. The processor here will be encapsulated as HandlerMethod11 HandlerMethod HandlerMethod = lookupHandlerMethod (lookupPath, request); 12 // make sure that the bean stores the instance 13 return (handlerMethod! = Null )? HandlerMethod. createWithResolvedBean (): null; 14}

 

// AbstractHandlerMethodMapping

Package org. springframework. web. servlet. handler; public abstract class implements acthandlermethodmapping <T> extends implements acthandlermapping implements InitializingBean {/*** Look up the best-matching handler method for the current request. * If multiple matches are found, the best match is selected. * @ param lookupPath mapping lookup path within the current servlet mapping * @ param request the current r Equest * @ return the best-matching handler method, or {@ code null} if no match * @ see # handleMatch (Object, String, HttpServletRequest) * @ see # handleNoMatch (Set, string, HttpServletRequest) */protected HandlerMethod lookupHandlerMethod (String lookupPath, HttpServletRequest request) throws Exception {List <Match> matches = new ArrayList <Match> (); // search for the matching condition RequestMappingInfo List from urlMap for direct equivalence match <T> d IrectPathMatches = this. urlMap. get (lookupPath); if (directPathMatches! = Null) {// addMatchingMappings (directPathMatches, matches, request);} if (matches. isEmpty () {// No choice but to go through all mappings // if No match exists, traverse all matching conditions of handlerMethods to find addMatchingMappings (this. handlerMethods. keySet (), matches, request);} if (! Matches. isEmpty () {Comparator <Match> comparator = new MatchComparator (getMappingComparator (request); Collections. sort (matches, comparator); 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 (); // There cannot be the same Optimal Match throw new IllegalStateException ("Ambiguous handler methods mapped for HTTP path'" + request. getRequestURL () + "': {" + m1 + "," + m2 + "}") ;}// the parameters parsed from the cached url in the request domain, mediaType, etc. Here RequestMappingHandlerMapping also overwrites handleMatch (bestMatch. mapping, lookupPath, request); return bestMatch. handlerMethod;} else {// RequestMappingHandlerMapping return handleNoMatch (handlerMethods. keySet (), lookupPath, request );}}}

 

// AbstractHandlerMethodMapping

Search for specific qualified RequestCondition

 1 package org.springframework.web.servlet.handler; 2 public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMapping implements InitializingBean { 3  4     private void addMatchingMappings(Collection<T> mappings, List<Match> matches, HttpServletRequest request) { 5         for (T mapping : mappings) { 6             T match = getMatchingMapping(mapping, request); 7             if (match != null) { 8                 matches.add(new Match(match, handlerMethods.get(mapping))); 9             }10         }11     }

 

// AbstractHandlerMethodMapping

1     /** 2      * Check if a mapping matches the current request and return a (potentially3      * new) mapping with conditions relevant to the current request.4      * @param mapping the mapping to get a match for5      * @param request the current HTTP servlet request6      * @return the match, or {@code null} if the mapping doesn't match7      */8     protected abstract T getMatchingMapping(T mapping, HttpServletRequest request);

 

Let's take a look at the implementation in RequestMappingInfoHandlerMapping and find the matching RequestCondition from RequestMappingInfo.

// RequestMappingInfoHandlerMapping

 1     /** 2      * Check if the given RequestMappingInfo matches the current request and 3      * return a (potentially new) instance with conditions that match the 4      * current request -- for example with a subset of URL patterns. 5      * @return an info in case of a match; or {@code null} otherwise. 6      */ 7     @Override 8     protected RequestMappingInfo getMatchingMapping(RequestMappingInfo info, HttpServletRequest request) { 9         return info.getMatchingCondition(request);10     }

 

// AbstractHandlerMethodMapping

1     /**2      * Invoked when a matching mapping is found.3      * @param mapping the matching mapping4      * @param lookupPath mapping lookup path within the current servlet mapping5      * @param request the current request6      */7     protected void handleMatch(T mapping, String lookupPath, HttpServletRequest request) {8         request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, lookupPath);9     }

 

RequestMappingInfoHandlerMapping overwrites it again. What is it for? Wait until you read HandlerAdaptor.

 1     /** 2      * Expose URI template variables, matrix variables, and producible media types in the request. 3      * @see HandlerMapping#URI_TEMPLATE_VARIABLES_ATTRIBUTE 4      * @see HandlerMapping#MATRIX_VARIABLES_ATTRIBUTE 5      * @see HandlerMapping#PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE 6      */ 7     @Override 8     protected void handleMatch(RequestMappingInfo info, String lookupPath, HttpServletRequest request) { 9         super.handleMatch(info, lookupPath, request);10 11         Set<String> patterns = info.getPatternsCondition().getPatterns();12         String bestPattern = patterns.isEmpty() ? lookupPath : patterns.iterator().next();13         request.setAttribute(BEST_MATCHING_PATTERN_ATTRIBUTE, bestPattern);14 15         Map<String, String> uriVariables = getPathMatcher().extractUriTemplateVariables(bestPattern, lookupPath);16         Map<String, String> decodedUriVariables = getUrlPathHelper().decodePathVariables(request, uriVariables);17         request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, decodedUriVariables);18 19         if (isMatrixVariableContentAvailable()) {20             request.setAttribute(HandlerMapping.MATRIX_VARIABLES_ATTRIBUTE, extractMatrixVariables(request, uriVariables));21         }22 23         if (!info.getProducesCondition().getProducibleMediaTypes().isEmpty()) {24             Set<MediaType> mediaTypes = info.getProducesCondition().getProducibleMediaTypes();25             request.setAttribute(PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE, mediaTypes);26         }27     }

 

 

 1     /** 2      * Invoked when no matching mapping is not found. 3      * @param mappings all registered mappings 4      * @param lookupPath mapping lookup path within the current servlet mapping 5      * @param request the current request 6      * @throws ServletException in case of errors 7      */ 8     protected HandlerMethod handleNoMatch(Set<T> mappings, String lookupPath, HttpServletRequest request) 9             throws Exception {10 11         return null;12     }

RequestMappingInfoHandlerMapping

// RequestMappingInfoHandlerMapping

 1     /** 2      * Iterate all RequestMappingInfos once again, look if any match by URL at 3      * least and raise exceptions accordingly. 4      * @throws HttpRequestMethodNotSupportedException if there are matches by URL 5      * but not by HTTP method 6      * @throws HttpMediaTypeNotAcceptableException if there are matches by URL 7      * but not by consumable/producible media types 8      */ 9     @Override10     protected HandlerMethod handleNoMatch(Set<RequestMappingInfo> requestMappingInfos,11             String lookupPath, HttpServletRequest request) throws ServletException {12 13         Set<String> allowedMethods = new LinkedHashSet<String>(4);14 15         Set<RequestMappingInfo> patternMatches = new HashSet<RequestMappingInfo>();16         Set<RequestMappingInfo> patternAndMethodMatches = new HashSet<RequestMappingInfo>();17 18         for (RequestMappingInfo info : requestMappingInfos) {19             if (info.getPatternsCondition().getMatchingCondition(request) != null) {20                 patternMatches.add(info);21                 if (info.getMethodsCondition().getMatchingCondition(request) != null) {22                     patternAndMethodMatches.add(info);23                 }24                 else {25                     for (RequestMethod method : info.getMethodsCondition().getMethods()) {26                         allowedMethods.add(method.name());27                     }28                 }29             }30         }31 32         if (patternMatches.isEmpty()) {33             return null;34         }35         else if (patternAndMethodMatches.isEmpty() && !allowedMethods.isEmpty()) {36             throw new HttpRequestMethodNotSupportedException(request.getMethod(), allowedMethods);37         }38 39         Set<MediaType> consumableMediaTypes;40         Set<MediaType> producibleMediaTypes;41         Set<String> paramConditions;42 43         if (patternAndMethodMatches.isEmpty()) {44             consumableMediaTypes = getConsumableMediaTypes(request, patternMatches);45             producibleMediaTypes = getProducibleMediaTypes(request, patternMatches);46             paramConditions = getRequestParams(request, patternMatches);47         }48         else {49             consumableMediaTypes = getConsumableMediaTypes(request, patternAndMethodMatches);50             producibleMediaTypes = getProducibleMediaTypes(request, patternAndMethodMatches);51             paramConditions = getRequestParams(request, patternAndMethodMatches);52         }53 54         if (!consumableMediaTypes.isEmpty()) {55             MediaType contentType = null;56             if (StringUtils.hasLength(request.getContentType())) {57                 try {58                     contentType = MediaType.parseMediaType(request.getContentType());59                 }60                 catch (IllegalArgumentException ex) {61                     throw new HttpMediaTypeNotSupportedException(ex.getMessage());62                 }63             }64             throw new HttpMediaTypeNotSupportedException(contentType, new ArrayList<MediaType>(consumableMediaTypes));65         }66         else if (!producibleMediaTypes.isEmpty()) {67             throw new HttpMediaTypeNotAcceptableException(new ArrayList<MediaType>(producibleMediaTypes));68         }69         else if (!CollectionUtils.isEmpty(paramConditions)) {70             String[] params = paramConditions.toArray(new String[paramConditions.size()]);71             throw new UnsatisfiedServletRequestParameterException(params, request.getParameterMap());72         }73         else {74             return null;75         }76     }

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.