初学者:理解spring-mvc的基本原理

1.0 spring-mvc的流程原理图


2.0 web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  
  <!-- 编码统一的过滤入口 -->
  	  <filter>
  	  	<filter-name>CharacterEncodingFilter</filter-name>
  	  	<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  	  	<!-- 更改编码为utf-8 ,其实就是更改CharacterEncodingFilter中的属性值-->
  	  	<init-param>
  	  		<param-name>encoding</param-name>
  	  		<param-value>UTF-8</param-value>
  	  	</init-param>
  	  </filter>
  	  
  	  <filter-mapping>
  	  	<filter-name>CharacterEncodingFilter</filter-name>
  	  	<url-pattern>/*</url-pattern>
  	  </filter-mapping>
  <!-- 编码统一的过滤入口 -->
  
  
  <!-- springMvc框架入口 -->
	  <servlet>
	    <servlet-name>reyco</servlet-name>
	    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	    <!-- 更改对应class里面的属性值,这里更改配置文件的路径 -->
	    <init-param>
	      <param-name>contextConfigLocation</param-name>
	      <param-value>classpath:spring-mvc.xml</param-value>
	    </init-param>
	    <load-on-startup>1</load-on-startup>
	  </servlet>
	  <servlet-mapping>
	    <servlet-name>reyco</servlet-name>
	    <url-pattern>*.do</url-pattern>
	  </servlet-mapping>
	<!-- springMvc框架入口 -->
</web-app>


所有的*.do请求都会经过中央调度器DispatcherServlet进行处理,DispatcherServlet中主要通过doDispath方法来处理*.do的请求

先来看下doDispath的源码

首先,doDispath利用处理器映射器通过req得到 处理器执行链,然后处理器适配器通过得到的处理器执行链找到合适的处理器,执行请求,返回mv

整个流程就是这样的

/**
	 * Process the actual dispatching to the handler.
	 * <p>The handler will be obtained by applying the servlet's HandlerMappings in order.
	 * The HandlerAdapter will be obtained by querying the servlet's installed HandlerAdapters
	 * to find the first that supports the handler class.
	 * <p>All HTTP methods are handled by this method. It's up to HandlerAdapters or handlers
	 * themselves to decide which methods are acceptable.
	 * @param request current HTTP request
	 * @param response current HTTP response
	 * @throws Exception in case of any kind of processing failure
	 */
	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;
					}
				}

				// Apply preHandle methods of registered interceptors.
				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;
					}
				}

				// Actually invoke the handler.
				mv = ha.handle(processedRequest, response, mappedHandler.getHandler());//处理器执行请求并返回mv

				// Do we need view name translation?
				if (mv != null && !mv.hasView()) {
					mv.setViewName(getDefaultViewName(request));
				}

				// Apply postHandle methods of registered interceptors.
				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);
			}
		}
	}



3.0 spring-mvc配置文件

<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"  
    xmlns:context="http://www.springframework.org/schema/context"  
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans   
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd   
        http://www.springframework.org/schema/mvc   
        http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd   
        http://www.springframework.org/schema/context   
        http://www.springframework.org/schema/context/spring-context-3.2.xsd   
        http://www.springframework.org/schema/aop   
        http://www.springframework.org/schema/aop/spring-aop-3.2.xsd   
        http://www.springframework.org/schema/tx   
        http://www.springframework.org/schema/tx/spring-tx-3.2.xsd "> 
    
   <!-- 注册组件扫描器    注意:这里是扫描包路径:
   		这里扫描包下面的文件,遇到@controller @Service @Repository @Component等注解的的java类,
   		就会将这些类注册为bean
   -->
   <context:component-scan base-package="com.xiaohao.handlers"/>
   
<!-- 内部资源视图解析器 根据返回的String来拼接成返回的url-->
   <!-- 
   <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
   		<property name="prefix" value="/WEB-INF/jsp/"/>返回视图前缀
   		<property name="suffix" value=".jsp"/>返回视图后缀
   </bean>
	-->
<!-- 内部资源视图解析器 根据返回的String来拼接成返回的url-->

   
<!-- 根据id返回视图 -->
   
   <!-- 根据id定义一个外部视图 -->
   <bean id="taobao" class="org.springframework.web.servlet.view.RedirectView">
   		<property name="url" value="https://www.taobao.com/"/>
   </bean>
   
   <!-- 根据id定义一个内部视图 -->
   <bean id="internalResource" class="org.springframework.web.servlet.view.JstlView">
   		<property name="url" value="/WEB-INF/jsp/welcome.jsp"/>
   </bean>
   
   <!-- 注册视图解析器  看名字就知道是根据bean name 返回视图-->
   <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
   
<!-- 根据id返回视图 -->
   
   
</beans> 

以上就是spring-mvc的基本配置和整个流程


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值