Servlet是什么

1. Servlet是服务器端运行的一个程序,是一个被编译好的Java类。它不是框架等。

2. Web容器的启动,需要依赖Servlet。当web服务器开始执行时,servlet类就被初始化

3. 当用户通过浏览器访问的时候,会输入URI,这个时候,web服务器就通过Servlet来分发请求执行不同的内容。

Servlet是有一个Jar包,里面包含了一些Servlet的相关设计和细节。

Spring的DispatcherServlet

Spring主要通过DispatcherServlet实现了Servlet。DispatcherServlet最上层也是继承的是HttpServlet这个类。

@Override
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
if (logger.isDebugEnabled()) {
String requestUri = urlPathHelper.getRequestUri(request);
logger.debug("DispatcherServlet with name '" + getServletName() + "' processing " + request.getMethod() +
" request for [" + requestUri + "]");
} // Keep a snapshot of the request attributes in case of an include,
// to be able to restore the original attributes after the include.
Map<String, Object> attributesSnapshot = null;
if (WebUtils.isIncludeRequest(request)) {
logger.debug("Taking snapshot of request attributes before include");
attributesSnapshot = new HashMap<String, Object>();
Enumeration<?> attrNames = request.getAttributeNames();
while (attrNames.hasMoreElements()) {
String attrName = (String) attrNames.nextElement();
if (this.cleanupAfterInclude || attrName.startsWith("org.springframework.web.servlet")) {
attributesSnapshot.put(attrName, request.getAttribute(attrName));
}
}
} // Make framework objects available to handlers and view objects.
request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource()); FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);
if (inputFlashMap != null) {
request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));
}
request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager); try {
doDispatch(request, response); //这边最终也是调用了doDispatch方法,该方法主要用来处理SPring框架的具体业务分发逻辑。
}
finally {
// Restore the original attribute snapshot, in case of an include.
if (attributesSnapshot != null) {
restoreAttributesAfterInclude(request, attributesSnapshot);
}
}
} //Spring框架最终的分发都是通过该方法的
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
int interceptorIndex = -1; try {
ModelAndView mv;
boolean errorView = false; try {
processedRequest = checkMultipart(request); // Determine handler for the current request.
mappedHandler = getHandler(processedRequest, false);
if (mappedHandler == null || mappedHandler.getHandler() == null) {
noHandlerFound(processedRequest, response);
return;
} // Determine handler adapter for the current request.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // Process last-modified header, if supported by the handler.
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (logger.isDebugEnabled()) {
String requestUri = urlPathHelper.getRequestUri(request);
logger.debug("Last-Modified value for [" + requestUri + "] is: " + lastModified);
}
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
} // 这里是处理前置拦截器
HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();
if (interceptors != null) {
for (int i = 0; i < interceptors.length; i++) {
HandlerInterceptor interceptor = interceptors[i];
if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {
triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);
return;
}
interceptorIndex = i;
}
} //处理最终的Action逻辑
mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // Do we need view name translation?
if (mv != null && !mv.hasView()) {
mv.setViewName(getDefaultViewName(request));
} //处理后置拦截器
if (interceptors != null) {
for (int i = interceptors.length - 1; i >= 0; i--) {
HandlerInterceptor interceptor = interceptors[i];
interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv);
}
}
}
catch (ModelAndViewDefiningException ex) {
logger.debug("ModelAndViewDefiningException encountered", ex);
mv = ex.getModelAndView();
}
catch (Exception ex) {
Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
mv = processHandlerException(processedRequest, response, handler, ex);
errorView = (mv != null);
} // Did the handler return a view to render?
if (mv != null && !mv.wasCleared()) {
render(mv, processedRequest, response);
if (errorView) {
WebUtils.clearErrorRequestAttributes(request);
}
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() +
"': assuming HandlerAdapter completed request handling");
}
} // Trigger after-completion for successful outcome.
triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);
} catch (Exception ex) {
// Trigger after-completion for thrown exception.
triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);
throw ex;
}
catch (Error err) {
ServletException ex = new NestedServletException("Handler processing failed", err);
// Trigger after-completion for thrown exception.
triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);
throw ex;
} finally {
// Clean up any resources used by a multipart request.
if (processedRequest != request) {
cleanupMultipart(processedRequest);
}
}
}

servlet和Spring的DispatcherServlet详解的更多相关文章

  1. spring mvc DispatcherServlet详解之前传---FrameworkServlet

    做项目时碰到Controller不能使用aop进行拦截,从网上搜索得知:使用spring mvc 启动了两个context:applicationContext 和WebapplicationCont ...

  2. (转载)spring mvc DispatcherServlet详解之一---处理请求深入解析

    要深入理解spring mvc的工作流程,就需要先了解spring mvc的架构: 从上图可以看到 前端控制器DispatcherServlet在其中起着主导作用,理解了DispatcherServl ...

  3. spring mvc DispatcherServlet详解之三---request通过ModelAndView中获取View实例的过程

    整个spring mvc的架构如下图所示: 上篇文件讲解了DispatcherServlet第二步:通过request从Controller获取ModelAndView.现在来讲解第三步:reques ...

  4. spring mvc DispatcherServlet详解之拾忆工具类utils

    DispatcherServlet的静态初始化 /** * Name of the class path resource (relative to the DispatcherServlet cla ...

  5. spring mvc DispatcherServlet详解之二---request通过Controller获取ModelAndView过程

    整个spring mvc的架构如下图所示: 上篇文件讲解了DispatcherServlet通过request获取控制器Controller的过程,现在来讲解DispatcherServletDisp ...

  6. spring mvc DispatcherServlet详解之一--request通过HandlerMaping获取控制器Controller过程

    整个spring mvc的架构如下图所示: 现在来讲解DispatcherServletDispatcherServlet的第一步:获取控制器. HandlerMapping HandlerMappi ...

  7. spring mvc DispatcherServlet详解之四---视图渲染过程

    整个spring mvc的架构如下图所示: 现在来讲解DispatcherServletDispatcherServlet的最后一步:视图渲染.视图渲染的过程是在获取到ModelAndView后的过程 ...

  8. spring mvc DispatcherServlet详解之interceptor和filter的区别

    首先我们看一下spring mvc Interceptor的功能及实现: http://wenku.baidu.com/link?url=Mw3GaUhCRMhUFjU8iIDhObQpDcbmmRy ...

  9. spring mvc DispatcherServlet详解之一---处理请求深入解析

    要深入理解spring mvc的工作流程,就需要先了解spring mvc的架构: 从上图可以看到 前端控制器DispatcherServlet在其中起着主导作用,理解了DispatcherServl ...

随机推荐

  1. codevs3162抄书问题(划分型dp)

    3162 抄书问题  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond   题目描述 Description 现在要把M本有顺序的书分给K个人复制(抄写),每 ...

  2. JS判断数组是否包含某元素

    我在学习ES6数组拓展时,发现了新增了不少了有趣的数组方法,突然想好工作中判断数组是否包含某个元素是非常常见的操作,那么这篇文章顺便做个整理. 1.for循环结合break 可能很多人第一会想到for ...

  3. mybatis多个参数查询问题

    一.话不多数,错误如下 Request processing failed; nested exception is org.mybatis.spring.MyBatisSystemException ...

  4. JavaScript--认识DOM

    文档对象模型DOM(Document Object Model)定义访问和处理HTML文档的标准方法.DOM 将HTML文档呈现为带有元素.属性和文本的树结构(节点树). 先来看看下面代码: 将HTM ...

  5. python爬虫值requests模块

    - 基于如下5点展开requests模块的学习 什么是requests模块 requests模块是python中原生的基于网络请求的模块,其主要作用是用来模拟浏览器发起请求.功能强大,用法简洁高效.在 ...

  6. [转]Linux中set,env和export这三个命令的区别

    转自:http://www.2cto.com/os/201306/223758.html Linux中set,env和export这三个命令的区别   set命令显示当前shell的变量,包括当前用户 ...

  7. Java继承体系中this的表示关系

    在继承关系下,父类中的this关键字并不总是表示父类中的变量和方法.this关键字的四种用法如前文所述,列举如下. 1) this(paras…); 访问其他的构造方法 2) this.xxx; 访问 ...

  8. Hibernate 配置双向多对多关联

    本文解决问题:Hibernate 中配置项目(Project) 员工(Employee)   双向多对多关联 方案一:直接配置双向多对多 方案二:配置第三个关联类(xml)   将多对多查分开来(形成 ...

  9. cmd 切换目录和配置环境变量

    记录一下: 在用cmd进行切换盘符的时候, 如果是从 C盘切换到其他盘的话: D:直接回车就行了. 如果是在同一个盘符内切换文件夹的话,cd D:\ComputerSoft\curl\curl-7.6 ...

  10. Linux 配置JDK + MyEclipse

    版本:Ubuntu16.04: jdK: Java SE Development Kit 8u102; My Eclipse: 10.6; JDK配置的细致步骤参见此处. 就一点要注意: 请使用代码进 ...