springMVC






Controller只是承担了Servlet的一部分功能

Spring MVC 中的五大核心组件:

  1. DispatcherServlet (前端控制器, 处理请求的入口)
  2. HandlerMapping (映射器对象, 用于管理url与对应controller的映射关系)
  3. Interceptors(拦截器,实现请求响应的共性处理)
  4. Controller (后端控制器-handler对象, 负责处理请求的控制逻辑)
  5. ViewResolver(视图解析器,解析对应的视图关系:前缀+view+后缀)-要自己进行配置,基于view找到对应的页面






package org.springframework.web.servlet;

import java.util.Locale;
public interface ViewResolver {

    View resolveViewName(String viewName, Locale locale) throws Exception;

}

Central dispatcher for HTTP request handlers/controllers
HTTP请求处理核心
DispatcherServlet 是发号指令的对象

public class DispatcherServlet extends FrameworkServlet {
}
public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware {
}
public abstract class HttpServletBean extends HttpServlet implements EnvironmentCapable, EnvironmentAware {
}
    <param-value>classpath:spring-configs.xml</param-value>

可以写多个

    <param-value>classpath:spring-*.xml</param-value>

企业里访问控制器的方法都这样写*.do

<servlet-mapping>
        <servlet-name>frontController</servlet-name>
        <url-pattern>*.do</url-pattern>
</servlet-mapping>
package org.springframework.web.servlet.handler;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.HandlerMapping;
public class HandlerMappingIntrospector implements CorsConfigurationSource {

    private final List<HandlerMapping> handlerMappings;

    public HandlerMappingIntrospector(ApplicationContext context) {
        this.handlerMappings = initHandlerMappings(context);
    }

    private static List<HandlerMapping> initHandlerMappings(ApplicationContext context) {
        Map<String, HandlerMapping> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(
                context, HandlerMapping.class, true, false);
        if (!beans.isEmpty()) {
            List<HandlerMapping> mappings = new ArrayList<HandlerMapping>(beans.values());
            AnnotationAwareOrderComparator.sort(mappings);
            return mappings;
        }
        return initDefaultHandlerMappings(context);
    }

    private static List<HandlerMapping> initDefaultHandlerMappings(ApplicationContext context) {
        Properties props;
        String path = "DispatcherServlet.properties";
        try {
            Resource resource = new ClassPathResource(path, DispatcherServlet.class);
            props = PropertiesLoaderUtils.loadProperties(resource);
        }
        catch (IOException ex) {
            throw new IllegalStateException("Could not load '" + path + "': " + ex.getMessage());
        }

        String value = props.getProperty(HandlerMapping.class.getName());
        String[] names = StringUtils.commaDelimitedListToStringArray(value);
        List<HandlerMapping> result = new ArrayList<HandlerMapping>(names.length);
        for (String name : names) {
            try {
                Class<?> clazz = ClassUtils.forName(name, DispatcherServlet.class.getClassLoader());
                Object mapping = context.getAutowireCapableBeanFactory().createBean(clazz);
                result.add((HandlerMapping) mapping);
            }
            catch (ClassNotFoundException ex) {
                throw new IllegalStateException("Could not find default HandlerMapping [" + name + "]");
            }
        }
        return result;
    }



    public List<HandlerMapping> getHandlerMappings() {
        return this.handlerMappings;
    }

    
    public MatchableHandlerMapping getMatchableHandlerMapping(HttpServletRequest request) throws Exception {
        HttpServletRequest wrapper = new RequestAttributeChangeIgnoringWrapper(request);
        for (HandlerMapping handlerMapping : this.handlerMappings) {
            Object handler = handlerMapping.getHandler(wrapper);
            if (handler == null) {
                continue;
            }
            if (handlerMapping instanceof MatchableHandlerMapping) {
                return ((MatchableHandlerMapping) handlerMapping);
            }
            throw new IllegalStateException("HandlerMapping is not a MatchableHandlerMapping");
        }
        return null;
    }

    @Override
    public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
        HttpServletRequest wrapper = new RequestAttributeChangeIgnoringWrapper(request);
        for (HandlerMapping handlerMapping : this.handlerMappings) {
            HandlerExecutionChain handler = null;
            try {
                handler = handlerMapping.getHandler(wrapper);
            }
            catch (Exception ex) {
                // Ignore
            }
            if (handler == null) {
                continue;
            }
            if (handler.getInterceptors() != null) {
                for (HandlerInterceptor interceptor : handler.getInterceptors()) {
                    if (interceptor instanceof CorsConfigurationSource) {
                        return ((CorsConfigurationSource) interceptor).getCorsConfiguration(wrapper);
                    }
                }
            }
            if (handler.getHandler() instanceof CorsConfigurationSource) {
                return ((CorsConfigurationSource) handler.getHandler()).getCorsConfiguration(wrapper);
            }
        }
        return null;
    }

    private static class RequestAttributeChangeIgnoringWrapper extends HttpServletRequestWrapper {

        public RequestAttributeChangeIgnoringWrapper(HttpServletRequest request) {
            super(request);
        }

        @Override
        public void setAttribute(String name, Object value) {
            // Ignore attribute change
        }
    }

}
package org.springframework.web.cors;
import javax.servlet.http.HttpServletRequest;
public interface CorsConfigurationSource {

    /**
     * Return a {@link CorsConfiguration} based on the incoming request.
     * @return the associated {@link CorsConfiguration}, or {@code null} if none
     */
    CorsConfiguration getCorsConfiguration(HttpServletRequest request);

}

DispatcherServlet渲染方法

protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
        // Determine locale for request and apply it to the response.
        Locale locale = this.localeResolver.resolveLocale(request);
        response.setLocale(locale);

        View view;
        if (mv.isReference()) {
            // We need to resolve the view name.
            view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);
            if (view == null) {
                throw new ServletException("Could not resolve view with name '" + mv.getViewName() +
                        "' in servlet with name '" + getServletName() + "'");
            }
        }
        else {
            // No need to lookup: the ModelAndView object contains the actual View object.
            view = mv.getView();
            if (view == null) {
                throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a " +
                        "View object in servlet with name '" + getServletName() + "'");
            }
        }

        // Delegate to the View object for rendering.
        if (logger.isDebugEnabled()) {
            logger.debug("Rendering view [" + view + "] in DispatcherServlet with name '" + getServletName() + "'");
        }
        try {
            if (mv.getStatus() != null) {
                response.setStatus(mv.getStatus().value());
            }
            view.render(mv.getModelInternal(), request, response);
        }
        catch (Exception ex) {
            if (logger.isDebugEnabled()) {
                logger.debug("Error rendering view [" + view + "] in DispatcherServlet with name '" +
                        getServletName() + "'", ex);
            }
            throw ex;
        }
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,651评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,468评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,931评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,218评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,234评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,198评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,084评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,926评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,341评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,563评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,731评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,430评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,036评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,676评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,829评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,743评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,629评论 2 354