Grails学习记录

grails的七个filter

1 charEncodingFilter
    org.springframework.web.filter.DelegatingFilterProxy
2 hiddenHttpMethod
    org.codehaus.groovy.grails.web.filters.HiddenHttpMethodFilter
            <dispatcher>FORWARD</dispatcher>
            <dispatcher>REQUEST</dispatcher>
3 AssetPipelineFilter
    asset.pipeline.AssetPipelineFilter
            <url-pattern>/assets/*</url-pattern>
            <dispatcher>REQUEST</dispatcher>
4 grailsWebRequest
    org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequestFilter
            <dispatcher>FORWARD</dispatcher>
            <dispatcher>REQUEST</dispatcher>
            <dispatcher>ERROR</dispatcher>

5 urlMapping
    org.codehaus.groovy.grails.web.mapping.filter.UrlMappingsFilter
            <url-pattern>/*</url-pattern>
            <dispatcher>FORWARD</dispatcher>
            <dispatcher>REQUEST</dispatcher>

此处过滤器分发合法的url

第一步获取uri:  String uri = urlHelper.getPathWithinApplication(request);


第二步判断是否合法

// not index request, no controllers, and no URL mappings for views, so it's not a Grails request
if (!"/".equals(uri) && isGrailsAppWithoutControllersAndRegexMappings()) {   
    processFilterChain(request, response, filterChain);    
    return;
}
//查找不需要过滤缓存中是否有包含但钱的uil包含则放行
if (uriExclusionCache.isUriExcluded(uri)) {
    processFilterChain(request, response, filterChain);
    return;
}
GrailsWebRequest webRequest = (GrailsWebRequest)request.
getAttribute(GrailsApplicationAttributes.WEB_REQUEST);
HttpServletRequest currentRequest = webRequest.getCurrentRequest();
String version = findRequestedVersion(webRequest);
//找到相应的MappingIfon
UrlMappingInfo[] urlInfos = urlMappingsHolder.matchAll(uri, currentRequest.getMethod(), version != null ? version : UrlMapping.ANY_VERSION);
WrappedResponseHolder.setWrappedResponse(response);boolean dispatched = false;

try {
    //过滤相应的MappingInfo
    for (UrlMappingInfo info : urlInfos) {
        if (info != null) {
            Object redirectInfo = info.getRedirectInfo();
            处理redirect
            if(redirectInfo != null) {
                final Map redirectArgs;
                if(redirectInfo instanceof Map) {
                    redirectArgs = (Map) redirectInfo;
                } else {
                    redirectArgs = CollectionUtils.newMap("uri", redirectInfo);
                }
                GrailsParameterMap params = webRequest.getParams();
                redirectArgs.put("params", params);


                ResponseRedirector redirector = new ResponseRedirector(linkGenerator);
                redirector.redirect(redirectArgs);
                dispatched = true;

                break;
            }
            // GRAILS-3369: The configure() will modify the
            // parameter map attached to the web request. So,
            // we need to clear it each time and restore the
            // original request parameters.
            webRequest.resetParams();
            //将MappingInfo中的参数传递到requet中(forword做准备)
            try {
                info.configure(webRequest);
                UrlConverter urlConverterToUse = urlConverter;
                GrailsApplication grailsApplicationToUse = application;
                GrailsClass controller = UrlMappingUtils.passControllerForUrlMappingInfoInRequest(webRequest, info, urlConverterToUse, grailsApplicationToUse);

                if(controller == null && info.getViewName()==null && info.getURI()==null) continue;
            }
            catch (Exception e) {
                if (e instanceof MultipartException) {
                    reapplySitemesh(request);
                    throw ((MultipartException)e);
                }
                LOG.error("Error when matching URL mapping [" + info + "]:" + e.getMessage(), e);
                continue;
            }
            
            dispatched = true;

            if (!WAR_DEPLOYED) {
                checkDevelopmentReloadingState(request);
            }

            request = checkMultipart(request);

            String nameOfview = info.getViewName();
            //转发request
            if (nameOfview == null || nameOfview.endsWith(GSP_SUFFIX) || nameOfview.endsWith(JSP_SUFFIX)) {
                if (info.isParsingRequest()) {
                    webRequest.informParameterCreationListeners();
                }
                String forwardUrl = UrlMappingUtils.forwardRequestForUrlMappingInfo(request, response, info);
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Matched URI [" + uri + "] to URL mapping [" + info + "], forwarding to [" + forwardUrl + "] with response [" + response.getClass() + "]");
                }
            }
            else {
                if (!renderViewForUrlMappingInfo(request, response, info, nameOfview)) {
                    dispatched = false;
                }
            }
            break;
        }
    }
}
finally {
    WrappedResponseHolder.setWrappedResponse(null);
}
//没有转发则返回错误
if (!dispatched) {
    Set<HttpMethod> allowedHttpMethods = allowHeaderForWrongHttpMethod ? allowedMethods(urlMappingsHolder, uri) : Collections.EMPTY_SET;

    if(allowedHttpMethods.isEmpty()) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("No match found, processing remaining filter chain.");
        }
        processFilterChain(request, response, filterChain);
    }
    else {
        response.addHeader(HttpHeaders.ALLOW, DefaultGroovyMethods.join(allowedHttpMethods, ","));
        response.sendError(HttpStatus.METHOD_NOT_ALLOWED.value());
    }
}

if (!dispatched) {
    Set<HttpMethod> allowedHttpMethods = allowHeaderForWrongHttpMethod ? allowedMethods(urlMappingsHolder, uri) : Collections.EMPTY_SET;

    if(allowedHttpMethods.isEmpty()) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("No match found, processing remaining filter chain.");
        }
        processFilterChain(request, response, filterChain);
    }
    else {
        response.addHeader(HttpHeaders.ALLOW, DefaultGroovyMethods.join(allowedHttpMethods, ","));
        response.sendError(HttpStatus.METHOD_NOT_ALLOWED.value());
    }
}


第三步判断是否在非过滤的数据中

if (uriExclusionCache.isUriExcluded(uri)) {
    processFilterChain(request, response, filterChain);
    return;
uriExclusionCache是一个缓存

static class UriExclusionCache {
    int maxWeightedCacheCapacity = 50000;

    //ConcurrentLinkedHashMap是谷歌的一个支持并发的LinkedHashMap
    Map<String, Boolean> exclusionCache =  new ConcurrentLinkedHashMap.Builder<String, Boolean>().maximumWeightedCapacity(maxWeightedCacheCapacity).weigher(new EntryWeigher<String, Boolean>() {
        @Override
        public int weightOf(String key, Boolean value) {
        return key.length();
        }
    }).build();
    private UrlMappingsHolder holder;
    UriExclusionCache(UrlMappingsHolder holder) {
        this.holder = holder;
    }
    boolean isUriExcluded(String uri) {
        //判断缓存中是否存在该uri
        Boolean isExcluded = exclusionCache.get(uri);
        if(isExcluded == null) {
        //判断本地的holder中是否有该缓存
        isExcluded = UrlMappingsFilter.isUriExcluded(holder, uri);
        if(!Environment.isDevelopmentMode()) {
            exclusionCache.put(uri, isExcluded);
        }
        }
        return isExcluded;
    }
}
//判断本地的holder中是否有该缓存
 public static boolean isUriExcluded(UrlMappingsHolder holder, String uri) {
        boolean isExcluded = false;
        @SuppressWarnings("unchecked")
        List<String> excludePatterns = holder.getExcludePatterns();
        if (excludePatterns != null && excludePatterns.size() > 0) {
            for (String excludePattern : excludePatterns) {
                int wildcardLen = 0;
                if (excludePattern.endsWith("**")) {
                    wildcardLen = 2;
                } else if (excludePattern.endsWith("*")) {
                    wildcardLen = 1;
                }
                if (wildcardLen > 0) {
                    excludePattern = excludePattern.substring(0,excludePattern.length() - wildcardLen);
                }
                if ((wildcardLen==0 && uri.equals(excludePattern)) || (wildcardLen > 0 && uri.startsWith(excludePattern))) {
                    isExcluded = true;
                    break;
                }
            }
        }
        return isExcluded;
    }






6 grailsCacheFilter


你可能感兴趣的:(Grails学习记录)