Spring:表现层框架
一般表现层框架面临的三大问题:
URL到框架的映射。
http请求参数绑定
http响应的生成和输出
那么Spring是如何解决这三大问题的呢?
回答:问题1
SpringMVC中的核心类及接口(以用户请求服务器到服务器响应用户请求顺序一一介绍)
rg.springframework.web.servlet包中定义的HandlerMapping接口
核心方法:HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
回到DispatcherServlet的处理流程,当DispatcherServlet接收到web请求后,由标准Servlet类处理方法doGet或者doPost,经过几次转发后,
将转发给HandlerMapping接口调用getHandler方法(HandlerMapping接口有多种实现类,此处,暂时不考虑HandlerMapping接口实现类的问题。)
getHandler方法解释如下:
1、获取web请求的HttpServletRequest对象
2、循环调用getHandler方法
3、在方法中,根据获取到HttpServletRequest对象遍历handlerMappings,直到getHandler方法获取的返回值不为null。
getHandler具体代码如下:
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
for (HandlerMapping hm : this.handlerMappings) {
if (logger.isTraceEnabled()) {
logger.trace(
"Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");
}
HandlerExecutionChain handler = hm.getHandler(request);
if (handler != null) {
return handler;
}
}
return null;
}
获取的返回对象HandlerExecutionChain就是对问题1的答案。
HandlerExecutionChain对象包含一个handler对象和拦截器数组。Handler翻译意思是处理器,那就是说,Handler就是url请求的响应对象。
SpirngMVC的第一个扩展点,就出现在这里。我们可以编写任意的HandlerMapping实现类,依据任何策略来决定一个web请求到HandlerExecutionChain对象的生成。可以说,从第一个核心接口的声明开始,SpringMVC就把自己的灵活性和野心暴露无疑:哥玩的就是”Open-Closed“。
HandlerExecutionChain对象是什么?有什么?什么作用?看下面源代码就知道了。
package org.springframework.web.servlet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.springframework.util.CollectionUtils;
public class HandlerExecutionChain {
private final Object handler;
private HandlerInterceptor[] interceptors;
private List<HandlerInterceptor> interceptorList;
public HandlerExecutionChain(Object handler) {
this(handler, null);
}
public HandlerExecutionChain(Object handler, HandlerInterceptor[] interceptors) {
if (handler instanceof HandlerExecutionChain) {
HandlerExecutionChain originalChain = (HandlerExecutionChain) handler;
this.handler = originalChain.getHandler();
this.interceptorList = new ArrayList<HandlerInterceptor>();
CollectionUtils.mergeArrayIntoCollection(originalChain.getInterceptors(), this.interceptorList);
CollectionUtils.mergeArrayIntoCollection(interceptors, this.interceptorList);
}
else {
this.handler = handler;
this.interceptors = interceptors;
}
}
public Object getHandler() {
return this.handler;
}
public void addInterceptor(HandlerInterceptor interceptor) {
initInterceptorList();
this.interceptorList.add(interceptor);
}
public void addInterceptors(HandlerInterceptor[] interceptors) {
if (interceptors != null) {
initInterceptorList();
this.interceptorList.addAll(Arrays.asList(interceptors));
}
}
private void initInterceptorList() {
if (this.interceptorList == null) {
this.interceptorList = new ArrayList<HandlerInterceptor>();
}
if (this.interceptors != null) {
this.interceptorList.addAll(Arrays.asList(this.interceptors));
this.interceptors = null;
}
}
public HandlerInterceptor[] getInterceptors() {
if (this.interceptors == null && this.interceptorList != null) {
this.interceptors = this.interceptorList.toArray(new HandlerInterceptor[this.interceptorList.size()]);
}
return this.interceptors;
}
@Override
public String toString() {
if (this.handler == null) {
return "HandlerExecutionChain with no handler";
}
StringBuilder sb = new StringBuilder();
sb.append("HandlerExecutionChain with handler [").append(this.handler).append("]");
if (!CollectionUtils.isEmpty(this.interceptorList)) {
sb.append(" and ").append(this.interceptorList.size()).append(" interceptor");
if (this.interceptorList.size() > 1) {
sb.append("s");
}
}
return sb.toString();
}
}
通过上述可知道URL的处理对象,但是DispatcherServlet又是如何去调用该handler,让其处理用户的请求的呢?
SpringMVC中的另外一个核心接口类HandlerAdapter:
代码如下:
package org.springframework.web.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface HandlerAdapter {
boolean supports(Object handler);
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
long getLastModified(HttpServletRequest request, Object handler);
}
DispatcherServlet会执行下面方法:
/**
* Return the HandlerAdapter for this handler object.
* @param handler the handler object to find an adapter for
* @throws ServletException if no HandlerAdapter can be found for the handler. This is a fatal error.
*/
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
for (HandlerAdapter ha : this.handlerAdapters) {
if (logger.isTraceEnabled()) {
logger.trace("Testing handler adapter [" + ha + "]");
}
if (ha.supports(handler)) {
return ha;
}
}
throw new ServletException("No adapter for handler [" + handler +
"]: Does your handler implement a supported interface like Controller?");
}
这段代码已经很明显了,HandlerExecutionChain中的handler对象会被作为参数传递进去,在DispatcherServlet类中注册的HandlerAdapter实现类列表会被遍历,然后返回第一个supports方法返回true的HandlerAdapter对象,用这个HandlerAdapter实现类中的handle方法处理handler对象,并返回ModelAndView这个包含了视图和数据的对象。HandlerAdapter就是SpringMVC提供的第三个扩展点(第二个扩展点为拦截器),你可以提供自己的实现类来处理handler对象。
分享到:
相关推荐
这个过程就涉及到URL映射。 URL映射规则在SpringMVC中主要通过`@RequestMapping`注解来实现。这个注解可以应用在类级别或方法级别,提供了多种方式来定义URL路径。 1. 类级别的`@RequestMapping`:此注解应用于...
在Spring MVC框架中,URL映射是连接前端请求与后端处理逻辑的关键步骤。这个"Spring简单URL映射例子"展示了如何配置并使用URL映射来处理HTTP GET请求,同时展示如何获取并处理GET方式传递的参数。让我们深入探讨这个...
URL 映射是诸如 Django、Ruby on Rails 等网页框架 (web frameworks) 的一个重要组件。对于从浏览器发来的 HTTP 请求,URL 映射模块会解析请求中的 URL 地址,并将其分派给相应的处理代码。现在,请你来实现一个简单...
这样,当遇到这样的URL时,框架会自动处理并跳转到相应的页面,极大地简化了代码。 其次,URLRoute支持自定义路由规则。开发者可以为每个URL模式定义处理函数或类,比如可以定义一个处理"myapp://news/article/:id...
- 映射方式:例如,将`/products/{category}/{id}`映射到处理程序,其中`{category}`和`{id}`可能是动态参数。 3. **Web框架中的URL映射** - 在不同的Web开发框架中,如ASP.NET、Django、Spring MVC等,都有各自...
通过在全局.asax文件中定义路由规则,我们可以将特定的URL模式映射到处理程序或控制器动作。例如,我们可能会设置一条规则,使得所有形如"/products/{category}/{product}"的请求都由ProductsController的...
总的来说,通过SSM框架中的Generator工具,我们可以快速、高效地生成项目所需的实体类、DAO接口和Mapper映射文件,极大地提高了开发效率,降低了出错的可能性。同时,这也遵循了DRY(Don't Repeat Yourself)原则,...
在Django中,URL映射到视图是整个框架处理Web请求的核心部分。URLconf(URL配置)是用于将URL与视图函数关联的机制。当用户请求一个页面时,Django会通过URLconf解析这个URL,从而找到对应的视图函数来处理这个请求...
在Django框架中,URL映射是非常重要的一个环节,它负责将用户的请求映射到相应的视图函数上。对于Django开发者而言,掌握URL映射规则能够帮助我们更高效地构建应用。 ##### 1.1 Django搜索路径 虽然这部分内容与...
本文实例讲述了Django框架视图层URL映射与反向解析。分享给大家供大家参考,具体如下: Django视图层主要工作就是衔接HTTP请求、python程序、HTML模板。 URL分发(URL dispatcher)映射配置可以被看作Django项目的...
3. 配置URL映射:在初始化阶段设置URL和Activity的映射关系。 4. 处理URL请求:在App的入口或合适的地方捕获URL请求并交给框架处理。 通过对`joyrun-ActivityRouter-a0bcae3`这个压缩包文件的分析,我们可以了解到...
`<add>`元素则用于定义具体的URL映射规则,其中`url`属性表示原始URL,`mappedUrl`属性表示映射到的实际URL。 例如,如果原始主页是`Homepage.aspx`,但你想将其改为`OriginalHome.aspx`,可以这样配置: ```xml ...
映射框架则是将这些接口与实际业务逻辑相连接的工具,它能够帮助开发者快速地构建和配置API,将请求路由到相应的处理函数,极大地提高了开发效率。 magic-api v2.1.1作为一个开源的HTTP接口映射框架,它的主要特性...
Spring MVC 基于URL的映射规则(注解版)是指在Spring MVC框架中,通过使用注解的方式来定义URL的映射规则。这篇文章将详细介绍了Spring MVC基于URL的映射规则(注解版),并提供了多种映射方式的示例。 首先,在...
通过配置Struts2的XML文件,可以定义Action与URL的映射,实现请求转发。 Spring框架则扮演着容器的角色,它提供了依赖注入(DI)和面向切面编程(AOP)等功能。DI允许开发者在运行时通过配置文件或注解来注入对象...
MyBatis映射生成工具是一种高效实用的开发辅助软件,主要功能是帮助开发者自动生成MyBatis框架下的DAO层、Bean类以及对应的XML映射文件。这个工具极大地提高了开发效率,减少了手动编写这些重复性代码的工作量。接...
这个框架看起来是用于帮助开发者将HTTP请求映射到特定的API功能,可能是一个Java或Python等编程语言中的库。由于标签为空,我们只能依据文件名和描述来推测其内容。 HTTP接口映射框架是开发Web服务时常用的工具,它...
这个映射器负责处理类和方法级别的`@RequestMapping`注解,将请求映射到相应的处理方法。 4. **注解开发步骤**: - 使用注解开发SpringMVC时,通常包括以下步骤: 1) 创建带有`@Controller`注解的类,定义处理...