SpringMVC入门

SpringMVC框架

什么是springmvc?
  • Spring web mvc和Struts2都属于表现层的框架,它是Spring框架的一部分,我们可以从Spring的整体结构中看得出来:

这里写图片描述

  • springmvc和spring无需通过中间整合层进行整合。
  • springmvc是一个基于mvc的web框架。

Web MVC

mvc设计模式在b/s系统下应用:

  • 我们现在站在框架角度思考MVC!!

还记得以前我们学习的Struts2吗??如果我们现在站在框架角度思考MVC,Filter就是我们的控制器,而Action就是我们的Model,JSP等视图显示技术当然还是我们的View。但是往往我们开发的时候却是站在网站角度,JSP等显示技术是我们的视图层,Service层和Dao层是我们的Model层,而Action是我们的控制层,而这个时候的Action也被叫做后端控制器。其实不管怎么想,这都是MVC架构思想。

这里写图片描述

springmvc框架

这里写图片描述

执行过程解说:

第一步:发起请求到前端控制器(DispatcherServlet)
第二步:前端控制器请求HandlerMapping查找 Handler

  • 可以根据xml配置、注解进行查找

第三步:处理器映射器HandlerMapping向前端控制器返回Handler
第四步:前端控制器调用处理器适配器去执行Handler
第五步:处理器适配器去执行Handler
第六步:Handler执行完成给适配器返回ModelAndView
第七步:处理器适配器向前端控制器返回ModelAndView

  • ModelAndView是springmvc框架的一个底层对象,包括 Model和view

第八步:前端控制器请求视图解析器去进行视图解析

  • 根据逻辑视图名解析成真正的视图(jsp)

第九步:视图解析器向前端控制器返回View
第十步:前端控制器进行视图渲染

  • 视图渲染将模型数据(在ModelAndView对象中)填充到request域

第十一步:前端控制器向用户响应结果

组件:

1、前端控制器DispatcherServlet(一般不需要程序员开发,但是架构师级别有可能去继承DispatcherServlet去写一些特殊的功能)
作用接收请求,响应结果,相当于转发器,中央处理器。有了DispatcherServlet减少了其它组件之间的耦合度。

2、处理器映射器HandlerMapping(不需要程序员开发)

  • 作用:根据请求的url查找Handler
  • HandlerMapping负责根据用户请求找到Handler即处理器,springmvc提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。

3、处理器适配器HandlerAdapter(不需要程序员开发)

  • 作用:按照特定规则(HandlerAdapter要求的规则)去执行Handler,这里的Handler必须实现Controller接口,才是一个Handler。
  • 通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。

4、处理器Handler(需要程序员开发)
注意:编写Handler时按照HandlerAdapter的要求去做,这样适配器才可以去正确执行Handler

5、视图解析器View resolver(不需要程序员开发)

  • 作用:进行视图解析,根据逻辑视图名解析成真正的视图(view)
  • View Resolver负责将处理结果生成View视图,View Resolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户。 springmvc框架提供了很多的View视图类型,包括:jstlView、freemarkerView、pdfView等。

6、视图View(需要程序员开发jsp)
View是一个接口,实现类支持不同的View类型(jsp、freemarker、pdf…)

入门程序

需求

以案例作为驱动。

功能需求:商品列表查询

环境准备

Spring4.3.7的jar包下载地址(已经包含SpringMVC)

老师用的完整包图
这里写图片描述

这里之所以要导入jstl.jar包的原因是我们jsp页面需要jstl.jar包(不写jstl标签不需要这个jar包),而不是我们SpringMVC中的JstlView这个视图需要jstl.jar。JstlView仅仅是SpringMVC的一个视图类罢了,一个视图类对应一个视图解析类。

Spring常用包的介绍

配置前端控制器

在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" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>SpringMVC</display-name>
  <!-- SpringMVC前端控制器 -->
  <servlet>
    <servlet-name>SpringMVC</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- contextConfigLocation配置SpringMVC加载的配置文件(配置处理器映射器、适配器等等)
        如果不配置contextConfigLocation,默认加载的是/WEB-INF/servlet名称-servlet.xml(SpringMVC-servlet.xml)
    -->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>SpringMVC</servlet-name>
    <!-- 
        第一种:*.action,访问以.action结尾由DispatcherServlet进行解析
        第二种:/,所以访问的地址由DispatcherServlet进行解析,对于静态文件的解析需要配置不让DispatcherServlet进行解析。使用此种方式可以实现 RESTful 风格的url 。
        第三种:/*,这样配置不对,使用这种配置,最终要转发到一个jsp页面时,仍然会由DispatcherServlet解析jsp地址,不能根据jsp页面找到Handler,会报错。
    -->
    <url-pattern>*.action</url-pattern>
  </servlet-mapping>

  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>

load-on-startup作用

为什么urlpattern不能为"/*" ??

Servlet url-pattern /与/区别,.action以及SpringMVC中/*解析出错过程分析
原生WEB,配置url-pattern属性值为/*转发时报错演示

配置处理器适配器

  • 在classpath下的springmvc.xml中配置处理器适配器
  • SimpleControllerHandlerAdapter:即简单控制器处理适配器,所有实现了org.springframework.web.servlet.mvc.Controller 接口的Bean作为
    Springmvc的后端控制器

这里写图片描述

<!-- 处理器适配器
    所有处理器适配器都实现HandlerAdapter接口
 -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>

通过查看源代码:

public class SimpleControllerHandlerAdapter implements HandlerAdapter {

    @Override
    public boolean supports(Object handler) {
        return (handler instanceof Controller);
    }

此适配器能执行实现Controller接口的Handler。

这里写图片描述

编写视图

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@taglib prefix="c"  uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">

    <title>My JSP 'itemsList.jsp' starting page</title>

    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">

  </head>

  <body>
        <!-- 这里使用的requestScope读取数据成功,就证明了我们的数据是放在requestScope里面的 -->
        <h3>欢迎来到首页</h3>
        <c:forEach items="${requestScope.itemsList }" var="item">
            <p>商品名字=${item.name}---商品价格=${item.price }---生产日期=<fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/>---描述=${item.detail }</p>
        </c:forEach>
  </body>
</html>

开发Handler

需要实现 controller接口,才能由org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter适配器执行。

public class ItemController implements Controller{

    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        /*
         * 调用service查找数据库,查询商品列表,这里使用静态数据模拟。
         */
        List<Item> items=new ArrayList<Item>();
        items.add(new Item("FireLang", 456.65, "技匠", null, new Date()));
        //创建ModelAndView
        ModelAndView modelAndView=new ModelAndView();
        //相当于 request 的 setAttribut,在jsp页面通过itemsList获取数据。
        modelAndView.addObject("itemsList", items);

        //指定跳转视图
        //为了安全起见(必须在我们的允许范围内访问视图),所以我们把视图放在了WEB-INF目录下。
        modelAndView.setViewName("/WEB-INF/content/itemsList.jsp");
        return modelAndView;
    }   
}

配置Handler

让我们编写的Handler在Spring容器中加载。(因为SpringMVC是Spring的一个子模块,所以Handler的bean加载就放在springmvc.xml核心配置文件里面)

<!-- 配置Handler -->
<bean name="/showItemsList.action" class="cn.domarvel.controller.ItemController"></bean>

配置处理器映射器

在classpath下的springmvc.xml中配置处理器映射器

<!-- 处理器映射器
    将bean的name作为url进行查找,需要在配置Handler时指定beanname(就是url)
 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>

配置视图解析器

需要配置解析jsp的视图解析器。

<!-- 视图解析器,默认使用JstlView作为视图,也就是JSP-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"></bean>

对于视图解析器讲解一个扩展使用方法:

<!-- ViewResolver -->
<!-- 当前视图解析器用于解析 JSP 页面。这种解析并不是真正意义上的解析,而只是把数据填充到request后,再根据网络路径做了一个页面转发或者页面包含 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 指定用哪儿一种视图作为显示,这里配置的是JSP,并且如果不配置,默认也是JstlView类作为视图。 -->
<!-- 一个视图类对应一个视图解析类。 -->
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>

关于这段话的解释:"这种解析并不是真正意义上的解析,而只是把数据填充到request后,再根据网络路径做了一个页面转发或者页面包含"

    //这个方法是org.springframework.web.servlet.view.InternalResourceViewResolver这个类的方法,这个类叫做视图解析器。
    @Override
    protected void renderMergedOutputModel(
            Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {

        // Expose the model object as request attributes.
        exposeModelAsRequestAttributes(model, request);//填充数据。把model数据填充到request中

        // Expose helpers as request attributes, if any.
        exposeHelpers(request);

        // Determine the path for the request dispatcher.
        String dispatcherPath = prepareForRendering(request, response);

        // Obtain a RequestDispatcher for the target resource (typically a JSP).
        RequestDispatcher rd = getRequestDispatcher(request, dispatcherPath);
        if (rd == null) {
            throw new ServletException("Could not get RequestDispatcher for [" + getUrl() +
                    "]: Check that the corresponding file exists within your web application archive!");
        }

        // If already included or response already committed, perform include, else forward.
        if (useInclude(request, response)) {
            response.setContentType(getContentType());
            if (logger.isDebugEnabled()) {
                logger.debug("Including resource [" + getUrl() + "] in InternalResourceView '" + getBeanName() + "'");
            }
            rd.include(request, response);
        }

        else {
            // Note: The forwarded resource is supposed to determine the content type itself.
            if (logger.isDebugEnabled()) {
                logger.debug("Forwarding to resource [" + getUrl() + "] in InternalResourceView '" + getBeanName() + "'");
            }
            rd.forward(request, response);//转发到JSP页面
        }
    }
InternalResourceViewResolver:支持JSP视图解析
viewClass:JstlView表示JSP模板页面需要使用JSTL标签库,所以classpath中必须包含jstl的相关jar 包;
prefix 和suffix:查找视图页面的前缀和后缀,最终视图的址为:
前缀+逻辑视图名+后缀,逻辑视图名需要在controller中返回ModelAndView指定,比如逻辑视图名为hello,则最终返回的jsp视图地址 “WEB-INF/jsp/hello.jsp
SpringMVC整体配置文件
<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 ">

<!-- 处理器映射器
    将bean的name作为url进行查找,需要在配置Handler时指定beanname(就是url)
 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>


<!-- 配置Handler -->
<bean id="itemsListId" name="/showItemsList.action" class="cn.domarvel.controller.ItemController"></bean>

<!-- 处理器适配器
    所有处理器适配器都实现HandlerAdapter接口
 -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>

<!-- 视图解析器
    解析JSP,默认使用JSTL标签,classpath下得有JSTL包
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"></bean>

</beans>

tips:常常我们开发的时候都是启用DEBUG模式进行开发!!

部署调试

处理器映射器根据url找不到Handler,报下边的错误。说明url错误。

这里写图片描述

处理器映射器根据url找到了Handler,转发的jsp页面找到,报下边的错误,说明jsp页面地址错误了。

这里写图片描述

非注解的处理器映射器和适配器

处理器映射器部分

DispatcherServlet

DispathcerServlet作为springmvc的中央调度器存在,DispatcherServlet创建时会默认从DispatcherServlet.properties文件加载springmvc所用的各各组件,如果在springmvc.xml中配置了组件则以springmvc.xml中配置的为准,DispatcherServlet的存在降低了springmvc各各组件之间的耦合度。

这里写图片描述

在DispatcherServlet.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

//默认配置的处理器映射器,一个是按照bean的name作为url查找,一个是注解
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
    org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping

//默认配置了两个适配器,一个是要实现Controller接口的适配器,一个是要实现HttpRequestHandler接口的适配器。当然还有注解方法。
org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
    org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
    org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter

org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\
    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

org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

所以我们的非注解程序开发中,在springmvc.xml中我们不用配置处理器映射器和处理器适配器就能够正常运行程序。只需要配置处理器的bean标签,配置name属性值作为url就行了。

HandlerMapping处理器映射器

HandlerMapping 负责根据request请求找到对应的Handler处理器及Interceptor拦截器,将它们封装在HandlerExecutionChain 对象中给前端控制器返回。处理器映射器(BeanNameUrlHandlerMapping,SimpleUrlHandlerMapping)都要实现HandlerMapping接口。

BeanNameUrlHandlerMapping

BeanNameUrl处理器映射器,根据请求的url与spring容器中定义的bean的name进行匹配,从而从spring容器中找到bean实例。

<!-- 处理器映射器
    将bean的name作为url进行查找,需要在配置Handler时指定beanname(就是url)
 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
SimpleUrlHandlerMapping

simpleUrlHandlerMapping是BeanNameUrlHandlerMapping的增强版本,它可以将url和处理器bean的id进行统一映射配置。用simpleUrlHandler还有另外一个原因,当BeanNameUrlHandlerMapping作为处理器映射器时,beanname就作为了url,这样就有了耦合性,笔者想的是url是url而beanname是beanname,这两个之间应该是没有耦合的,所以我们应该使用simpleUrlHandlerMapping降低耦合。

<!-- 简单url映射 -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <props>
            <!-- 对itemsListId进行url映射,url是/showItemsList1.action -->
            <!-- 对同一个Handler后端处理器可以配置多个url进行解析 -->
            <!-- 多个映射处理器类可以共存,并且可以写相同的url -->
            <prop key="/showItemsList1.action">itemsListId</prop>
            <prop key="/showItemsList2.action">itemsListId</prop>
            <prop key="/showItemsList.action">itemsListId</prop>
            <!-- 在这种配置Url里面可以使用通配符*或者?。*匹配任意0-多个,?匹配任意一个。 -->
            <!-- 比如 key="/showItemsList*.action",能够让showItemsList56656.action访问 -->
        </props>
    </property>
</bean>
  • 多个映射器可以并存,前端控制器判断url能让哪些映射器映射,就让正确的映射器处理。

处理器适配器部分

HandlerAdapter处理器适配器

HandlerAdapter会根据适配器接口对后端控制器进行包装(适配),包装后即可对处理器进行执行,通过扩展处理器适配器可以执行多种类型的处理器,这里使用了适配器设计模式。处理器适配器都要实现HandlerAdapter接口。

SimpleControllerHandlerAdapter

SimpleControllerHandlerAdapter简单控制器处理器适配器,所有实现了org.springframework.web.servlet.mvc.Controller 接口的Bean通过此适配器进行适配、执行。

适配器配置如下:

<!-- 处理器适配器
    所有处理器适配器都实现HandlerAdapter接口
 -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
HttpRequestHandlerAdapter

HttpRequestHandlerAdapter,http请求处理器适配器,所有实现了org.springframework.web.HttpRequestHandler 接口的Bean通过此适配器进行适配、执行。

适配器配置如下:

<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>

Controller实现如下:

public class ItemListController implements HttpRequestHandler{

    @Override
    public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*
         * 调用service查找数据库,查询商品列表,这里使用静态数据模拟。
         */
        List<Item> items=new ArrayList<Item>();
        items.add(new Item("FireLang", 456.65, "技匠", null, new Date()));

        request.setAttribute("itemsList", items);
        request.getRequestDispatcher("/WEB-INF/content/itemsList.jsp").forward(request, response);
    }
}

注意:因为这是创建的一个新的Hander,所以我们必须要在springmvc.xml核心配置文件里面创建该Handler的bean对象。

从上边可以看出此适配器器的handleRequest方法没有返回ModelAndView,可通过response修改定义响应内容,比如返回json数据:

response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("json串");

目前springmvc.xml整体文件配置如下:

<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 ">

<!-- 处理器映射器
    将bean的name作为url进行查找,需要在配置Handler时指定beanname(就是url)
 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>

<!-- 简单url映射 -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <props>
            <!-- 对itemsListId进行url映射,url是/showItemsList1.action -->
            <!-- 对同一个Handler后端处理器可以配置多个url进行解析 -->
            <!-- 多个映射处理器类可以共存,并且可以写相同的url -->
            <prop key="/showItemsList1.action">itemsListId</prop>
            <prop key="/showItemsList2.action">itemsListId</prop>
            <prop key="/showItemsList.action">itemsListId</prop>
        </props>
    </property>
</bean>

<!-- 配置Handler -->
<bean id="itemsListId" name="/showItemsList.action" class="cn.domarvel.controller.ItemController"></bean>

<!-- 配置ItemListController-HttpHandler -->
<bean id="itemsListId-httpAdapter" name="/showItemsList-httpAdapter.action" class="cn.domarvel.controller.ItemListController"></bean>

<!-- 处理器适配器
    所有处理器适配器都实现HandlerAdapter接口
 -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>

<!-- 配置HttpRequestHandlerAdapter适配器 -->
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"></bean>

<!-- 视图解析器
    解析JSP,默认使用JSTL标签,classpath下得有JSTL包
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"></bean>

</beans>

总结:

对于多个处理器映射器和多个处理器适配器是可以共存的!!

因为一个处理器可能只有某个适配器才能够执行,并且一个处理器只有某个处理器映射器能够找到!!

SpringMVC注解开发

提示:

  • 如果有读者要看SpringMVC中的源码,你要从Servlet的service方法看起。
  • 如果你看到了很多方法的空实现,那么该实现是由子类实现。这种方式看似简单,其实是一个设计模式—>模板模式。
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值