摘要:源码仓库本文仓库三层结构表现层模型业务层持久层工作流程用户前端控制器用户发送请求前端控制器后端控制器根据用户请求查询具体控制器后端控制器前端控制器处理后结果前端控制器视图视图渲染视图前端控制器返回视图前端控制器用户响应结
SpringMvc
【源码仓库】
【本文仓库】
表现层
MVC模型
业务层
service
持久层
dao
工作流程</>复制代码
用户->前端控制器:用户发送请求
前端控制器-> 后端控制器:根据用户请求查询具体控制器
后端控制器-->前端控制器:处理后结果
前端控制器--> 视图:视图渲染
视图-->前端控制器:返回视图
前端控制器--> 用户:响应结果
简单案例
依赖
</>复制代码
4.0.0
com.huifer
mySpringMvcBook
1.0-SNAPSHOT
war
UTF-8
UTF-8
1.8
5.1.5.RELEASE
4.12
org.springframework
spring-beans
${spring.version}
org.springframework
spring-core
${spring.version}
org.springframework
spring-context
${spring.version}
org.springframework
spring-expression
${spring.version}
org.springframework
spring-aspects
${spring.version}
aopalliance
aopalliance
1.0
org.springframework
spring-webmvc
${spring.version}
org.springframework
spring-web
${spring.version}
javax.servlet.jsp.jstl
jstl
1.2
javax.servlet
servlet-api
2.5
org.projectlombok
lombok
1.18.4
com.fasterxml.jackson.core
jackson-databind
2.9.3
com.fasterxml.jackson.core
jackson-core
2.9.3
com.fasterxml.jackson.core
jackson-annotations
2.9.3
src/main/java
**/*.xml
org.apache.maven.plugins
maven-compiler-plugin
1.8
1.8
UTF-8
spring-config
</>复制代码
web.xml
</>复制代码
springmvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:spring-mvc-config.xml
2
springmvc
/
controller
</>复制代码
@Controller
@RequestMapping("item")
public class ItemController {
@ResponseBody
@GetMapping("/query")
public ModelAndView query() throws Exception {
List- itemList = new ArrayList<>();
itemList.add(new Item("吃的", 3.3, new Date()));
itemList.add(new Item("玩的", 3.3, new Date()));
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("itemList", itemList);
modelAndView.setViewName("/WEB-INF/jsp/item.jsp");
return modelAndView;
}
}
item.JSP
</>复制代码
<%--
Created by IntelliJ IDEA.
User: huifer
Date: 2019/3/10
Time: 11:26
To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false" %>
ItemList
ITEM
${itemList}
根据tomcat的web.xml配置可以看到 / 和jsp的拦截是分开的 ,而我们直接用一个/*来拦截那么tomcat将不知道用什么来处理
spring-mvc大致流程源码翻阅从配置文件中知道前端控制器DispatcherServlet
</>复制代码
springmvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:spring-mvc-config.xml
2
在org.springframework.web.servlet.DispatcherServlet 看下面两个方法
doService 将访问的数据接收到交给doDispatch
doDispatch 具体调度
</>复制代码
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
try {
ModelAndView mv = null;
Object dispatchException = null;
try {
processedRequest = this.checkMultipart(request);
multipartRequestParsed = processedRequest != request;
// 加载handler
mappedHandler = this.getHandler(processedRequest);
if (mappedHandler == null) {
this.noHandlerFound(processedRequest, response);
return;
}
// handler适配器
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
return;
}
}
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// 适配器执行操作
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
this.applyDefaultViewName(processedRequest, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv);
} catch (Exception var20) {
dispatchException = var20;
} catch (Throwable var21) {
dispatchException = new NestedServletException("Handler dispatch failed", var21);
}
// 操作结果返回
this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
} catch (Exception var22) {
this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
} catch (Throwable var23) {
this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));
}
} finally {
if (asyncManager.isConcurrentHandlingStarted()) {
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
} else if (multipartRequestParsed) {
this.cleanupMultipart(processedRequest);
}
}
}
handler怎么来
initHandlerMappings(context)
</>复制代码
protected void initStrategies(ApplicationContext context) {
this.initMultipartResolver(context);
this.initLocaleResolver(context);
this.initThemeResolver(context);
this.initHandlerMappings(context);
this.initHandlerAdapters(context);
this.initHandlerExceptionResolvers(context);
this.initRequestToViewNameTranslator(context);
this.initViewResolvers(context);
this.initFlashMapManager(context);
}
</>复制代码
private void initHandlerMappings(ApplicationContext context) {
this.handlerMappings = null;
if (this.detectAllHandlerMappings) {
Map matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
if (!matchingBeans.isEmpty()) {
this.handlerMappings = new ArrayList(matchingBeans.values());
AnnotationAwareOrderComparator.sort(this.handlerMappings);
}
} else {
try {
HandlerMapping hm = (HandlerMapping)context.getBean("handlerMapping", HandlerMapping.class);
this.handlerMappings = Collections.singletonList(hm);
} catch (NoSuchBeanDefinitionException var3) {
}
}
if (this.handlerMappings == null) {
// 读取默认配置文件
this.handlerMappings = this.getDefaultStrategies(context, HandlerMapping.class);
if (this.logger.isTraceEnabled()) {
this.logger.trace("No HandlerMappings declared for servlet "" + this.getServletName() + "": using default strategies from DispatcherServlet.properties");
}
}
}
默认配置文件
handler适配器也在配置文件中
</>复制代码
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
Iterator var2 = this.handlerAdapters.iterator();
while(var2.hasNext()) {
HandlerAdapter adapter = (HandlerAdapter)var2.next();
// 是否能够适配
if (adapter.supports(handler)) {
return adapter;
}
}
}
throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}
HttpRequestHandlerAdapter
</>复制代码
public class HttpRequestHandlerAdapter implements HandlerAdapter {
public HttpRequestHandlerAdapter() {
}
// 判断是否是当前类支持的适配器
public boolean supports(Object handler) {
return handler instanceof HttpRequestHandler;
}
// 适配器执行操作
@Nullable
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
((HttpRequestHandler)handler).handleRequest(request, response);
return null;
}
public long getLastModified(HttpServletRequest request, Object handler) {
return handler instanceof LastModified ? ((LastModified)handler).getLastModified(request) : -1L;
}
}
视图解析
</>复制代码
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, @Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv, @Nullable Exception exception) throws Exception {
boolean errorView = false;
if (exception != null) {
if (exception instanceof ModelAndViewDefiningException) {
this.logger.debug("ModelAndViewDefiningException encountered", exception);
mv = ((ModelAndViewDefiningException)exception).getModelAndView();
} else {
Object handler = mappedHandler != null ? mappedHandler.getHandler() : null;
mv = this.processHandlerException(request, response, handler, exception);
errorView = mv != null;
}
}
if (mv != null && !mv.wasCleared()) {
// 这个地方在做渲染
this.render(mv, request, response);
if (errorView) {
WebUtils.clearErrorRequestAttributes(request);
}
} else if (this.logger.isTraceEnabled()) {
this.logger.trace("No view rendering, null ModelAndView returned.");
}
if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
if (mappedHandler != null) {
mappedHandler.triggerAfterCompletion(request, response, (Exception)null);
}
}
}
</>复制代码
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
Locale locale = this.localeResolver != null ? this.localeResolver.resolveLocale(request) : request.getLocale();
response.setLocale(locale);
String viewName = mv.getViewName();
View view;
if (viewName != null) {
// 视图解析器
view = this.resolveViewName(viewName, mv.getModelInternal(), locale, request);
if (view == null) {
throw new ServletException("Could not resolve view with name "" + mv.getViewName() + "" in servlet with name "" + this.getServletName() + """);
}
} else {
view = mv.getView();
if (view == null) {
throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a View object in servlet with name "" + this.getServletName() + """);
}
}
if (this.logger.isTraceEnabled()) {
this.logger.trace("Rendering view [" + view + "] ");
}
try {
if (mv.getStatus() != null) {
response.setStatus(mv.getStatus().value());
}
// 视图的渲染函数渲染到页面上
view.render(mv.getModelInternal(), request, response);
} catch (Exception var8) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Error rendering view [" + view + "]", var8);
}
throw var8;
}
}
</>复制代码
@Nullable
protected View resolveViewName(String viewName, @Nullable Map model, Locale locale, HttpServletRequest request) throws Exception {
if (this.viewResolvers != null) {
Iterator var5 = this.viewResolvers.iterator();
while(var5.hasNext()) {
// 视图解析器
ViewResolver viewResolver = (ViewResolver)var5.next();
View view = viewResolver.resolveViewName(viewName, locale);
if (view != null) {
return view;
}
}
}
return null;
}
spring-mvc请求具体流程图
</>复制代码
用户->前端控制器
org.springframework.web.servlet.DispatcherServlet
用来接收响应以及返回响应结果:1.用户发送请求
前端控制器
org.springframework.web.servlet.DispatcherServlet
用来接收响应以及返回响应结果 -> HandlerMapper : 2.根据url进行处理
HandlerMapper -> 前端控制器
org.springframework.web.servlet.DispatcherServlet
用来接收响应以及返回响应结果:3.将handlerMapper处理结果给前端控制器
前端控制器
org.springframework.web.servlet.DispatcherServlet
用来接收响应以及返回响应结果-> HandlerAdapter:4.给适配器确认具体的适配器,比如我们这里给了HttpRequestHandlerAdapter
HandlerAdapter ->ModelAndView:5.用来执行业务操作
ModelAndView ->HandlerAdapter: 6.执行完成给HandlerAdapter返回
HandlerAdapter->前端控制器
org.springframework.web.servlet.DispatcherServlet
用来接收响应以及返回响应结果:7.返回一个modelAndView
前端控制器
org.springframework.web.servlet.DispatcherServlet
用来接收响应以及返回响应结果-> ViewResolver 视图解析器 :8.将第7步中的view进行解析
ViewResolver 视图解析器->前端控制器
org.springframework.web.servlet.DispatcherServlet
用来接收响应以及返回响应结果:9.解析结果返回
前端控制器
org.springframework.web.servlet.DispatcherServlet
用来接收响应以及返回响应结果 -> View : 9.将model渲染到view中
View->前端控制器
org.springframework.web.servlet.DispatcherServlet
用来接收响应以及返回响应结果: 10.view 结果返回给前端控制器
前端控制器
org.springframework.web.servlet.DispatcherServlet
用来接收响应以及返回响应结果 --> 用户:查看到完整的网页
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/73641.html
摘要:处理器是继前端控制器的后端控制器,在的控制下对具体的用户请求进行处理。由于涉及到具体的用户业务请求,所以一般情况需要程序员根据业务需求开发。 1、mcv整体架构和流程 showImg(https://segmentfault.com/img/bV55Qq?w=860&h=406); 用户发送请求至前端控制器 DispatcherServlet DispatcherServlet 收到...
摘要:框架搭建首先下载相应的包,对于包有两种方式使用创建依赖从而导入所需的包。总结主要进行页面的请求接受与响应。组件包括前端控制器,处理器映射器,处理器适配器,视图解析器,处理器,视图。 我之前的文章介绍了如何搭建SSH框架以及如何利用这一框架来进行web应用开发,最近我又接触了SSM框架即Spring+SpringMVC+Mybatis三大框架的整合,而且目前该框架就SSH框架而言使用的较...
摘要:入门笔记简介是一种基于的实现了设计模式的请求驱动类型的轻量级框架,是系开源项目中的一个,和配合使用。配置在中需要添加使用的和映射规则。入门较快,而掌握起来相对较难。 SpringMVC入门笔记 1. 简介 Spring MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架 ,是Spring系开源项目中的一个,和IoC配合使用。通过策略接口,Spring...
摘要:关键注解的关键注解主要有其中主要是用于标记该类是一个控制器,用于指示的哪一个类或方法来处理请求动作,即用于标识具体的处理器。默认已经装配了作为组件的实现类,而由使用,将请求信息转换为对象。 关键注解 springmvc的关键注解主要有@Controller/@RequestMapping/@RequestParam/@PathVariable/@RequestHeader/@Cooki...
阅读 1678·2021-11-02 14:48
阅读 3779·2019-08-30 15:56
阅读 2844·2019-08-30 15:53
阅读 3282·2019-08-30 14:09
阅读 3195·2019-08-30 12:59
阅读 2928·2019-08-29 18:38
阅读 2782·2019-08-26 11:41
阅读 2351·2019-08-23 16:45