SpringMVC(⼀)框架设计及流程
Spring MVC(⼀)框架设计及流程
SpringMVC框架设计
框架设计图如下
上图是SpringMVC框架运⾏的流程。处理请求先到达控制器(Controller),控制器的作⽤是进⾏请求转
发,这样它会根据请求的内容去访问模型层(Model);在现今互联⽹体系中,数据主要从数据库和NoSQL中来,⽽且对于数据库⽽⾔往往还存在事务的机制,为了适应这样的变化,设计者会把模型层再细分为两层,即服务层(Service)和数据访问层(DAO);当控制器获取到由模型层返回的数据后,将数据渲染到视图中,这样就能够展⽰给⽤户了。
SpringMVC流程
流程图
流程和组件是SpringMVC的核⼼。
SpringMVC的流程都是围绕着DispatcherServlet⽽⼯作的。严格来说,springMVC处理请求并⾮⼀定需要经过全流程,有时候⼀些流程并不存在,⽐如我们加⼊@ResponseBody注解时,是没有经过视图解析器和视图渲染的,关于这个后⾯会讨论到。
⾸先,在Web服务器启动的过程中,如果在Spring Boot的机制下启⽤SpirngMVC,它就开始初始化⼀些重要组件,
如DispactherServlert、HandlerAdatper的实现类RequestMappingHandlerAdatper等对象组件。关于组件的初始化,我们在spring-webmvc-xxx.jar包的属性⽂件DispatcherServler.properties,它定义的对象都是在SpringMVC开始时就初始化,并且存放在SpringIoC容器中。其源码如下
DispatcherServler.properties源码
# Default implementation classes for DispatcherServlet's strategy interfaces.
# Used as fallback when no matching beans are found in the DispatcherServlet context.
# Not meant to be customized by application developers.
#国际化解析器
org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
#主题解析器
org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
# HandlerMapping实例
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
org.springframework.web.hod.annotation.RequestMappingHandlerMapping
#处理器适配器
org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
org.springframework.web.hod.annotation.RequestMappingHandlerAdapter
#处理器异常解析器
org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.hod.annotation.ExceptionHandlerExceptionResolve r,\
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
#策略视图名称转换器,当没有返回视图逻辑名称的时候,通过它可以⽣成默认的视图名称
org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
#视图解析器
org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
#FlashMap管理器,不常⽤
org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager
这些组件会在SpringMVC得到初始化,所以我们并不需要太多的配置就能够开发SpringMVC程序。
普通视图
定义控制器
@RequestMapping(value ="/person")
@Controller
public class PersonController {
//注⼊⽤户服务类
@Autowired
PersonService personService;
//展⽰⼈员详情
@RequestMapping("/details")
public ModelAndView details(Long id){
/
/访问模型层得到数据
Person perosn = Person(id);
//模型和视图
ModelAndView mv =new ModelAndView();
//定义模型视图
mv.setViewName("person/details");
//加⼊数据模型
mv.addObject("person", perosn);
//返回视图
return mv;
}
}
@Controller:表明这是⼀个控制器
@RequestMapping:代表请求路径和控制器(或⽅法)的映射关系,它会在Web服务启动SpringMVC的时,就被扫描到HandlerMapping 的机制中存储,之后再⽤户发起请求被DispatcherServlert拦截后,通过URI和其他的条件,通过HandlerMapper机制就能够到对应的控制器或其⽅法进⾏响应。只是通过HandlerMapping返回的是⼀个HandlerExecutionChain对象,源码如下
HandlerExecutionChain源码
public class HandlerExecutionChain {
//⽇志
private static final Log logger = Log(HandlerExecutionChain.class);
//处理器
private final Object handler;
//数组
@Nullable
private HandlerInterceptor[] interceptors;
//列表
@Nullable
private List<HandlerInterceptor> interceptorList;
//当前下标
private int interceptorIndex;
//....
}
HandlerExecutionChain对象包含⼀个处理器(handler)。这⾥的处理器就是对控制器(controller)
的包装。因为我们的控制器⽅法可能存在参数,那么处理器就可以读⼊http和上下⽂的相关参数,然后再传递给控制器⽅法。⽽在控制器执⾏完成返回后,处理器⼜可以通过配置信息和对控制器的返回结果进⾏处理。可以看出,处理器包含了控制器⽅法的逻辑,此外还有处理器的(interceptor),这样就能够通过拦截处理器进⼀步增强处理器的功能。
得到了处理器(handler)。还需要去运⾏,但是我们有普通的http请求,也有按BeanName的请求,设置是WebSocket的请求,所以它还需要⼀个适配器去运⾏HandlerExecutionChain对象包含的处理器,这就是HandlerAdapter接⼝定义的实现类。从源码中可以看到SpringMVC中最常⽤的HandlerAdapter的实现类,便是HttpRequestHandlerAdapter。通过请求的类型,DispatcherServlet就会到它来执⾏Web请求的HandlerExecutionChain对象包含的内容,这样就能够执⾏我们的处理器(handler)了。
在处理器调⽤控制器时,它⾸先通过模型层得到数据,再放⼊数据模型中,最后将返回模型和视图对象(ModelAndView),这⾥控制器设置的视图名称设置为"person/details"这样就⾛到了视图解析器(ViewResolver),去解析视图逻辑名称了。
SpringMVC的ViewResolver的实现类是InternalResourceViewResolver,为了定制,我们可以在application.properties⽂件中进⾏配置
spring.mvc.view.prefix=/
spring.mvc.view.suffix=.html
通过这样的配置,就能能在Spring Boot机制下定织InternalResouceViwResolver这个视图解析器的初始化,也就是在返回视图名称之后,它会以前缀(prefix)和后缀(suffix)以及视图的名称组成全路径定位视图。例如,在控制器返回的"person/details",这⾥前缀为/,等于spring boot默认路径"/src/main/resources/templates",那么它就会到"/src/main/resources/templates/person.html"作为视图。
视图解析器定位到视图后,视图的作⽤是将数据模型(Model)渲染,这样就能够响应数据的请求。这⼀步就是视图将数据模型渲染(View)出来,⽤来展⽰给⽤户看。
/person/details.html
<!DOCTYPE html>
<html th="">
<head>
<meta charset="UTF-8">
spring ioc注解<meta charset="UTF-8">
<title>⽤户详情</title>
</head>
<body>
<center>
<table border="1">
<tr>
<td>标签</td>
<td>值</td>
</tr>
<tr>
<td>⽤户编号</td>
<td text="${person.id}"></td>
</tr>
<tr>
<td>⽤户名称</td>
<td text="${person.personName}"></td>
</tr>
<tr>
<td>⽤户备注</td>
<td text="${}"></td>
</tr>
</table>
</center>
</body>
</html>
这⾥因为我们的控制器⾥绑定数据模型的时候,属性名称为person,⽽属性为person对象,所以就有了${person.id}代表perosn对象的id属性,其余属性是⼀样的。
流程如下
JSON视图
有时候我们需要的只是JSON数据集,因为⽬前前后台分离的趋势,使⽤JSON已经是主流的⽅式。正如@ResponseBody注解表明⽅法⼀样,springMVC会把数据转换为JSON数据集,但是这⾥不谈@ResponseBody,因为它会采⽤处理器内部的机制。这⾥先
⽤MappingJackson2JsonView转换出JSON。
//使⽤json视图
@RequestMapping("/detailsForJson")
public ModelAndView detailsForJson(Long id){
Person person = Person(id);
ModelAndView mv =new ModelAndView();
MappingJackson2JsonView jsonView =new MappingJackson2JsonView();
mv.setView(jsonView);
mv.addObject("person", person);
return mv;
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论