Springmvc学习笔记(一)

学习笔记

1 Springmvc框架

1.1 什么是springmvc

springmvc是spring框架的一个模块,springmvc和spring无需通过中间整合层整合。
springmvc是一个基于mvc的web框架。

在这里插入图片描述

1.2 mvc在b/s系统下的应用

mvc是一个设计模式,mvc在b/s系统下的应用

在这里插入图片描述

1.3 springmvc框架

在这里插入图片描述

2 入门程序

2.1 环境

  • 数据库环境:sqlserver2008
  • Java环境:jdk1.7.0_72
  • eclipse indigo
  • springmvc版本:spring4.2
    在这里插入图片描述

2.2 需求

springmvc和mybatis使用一个案例(商品订单)

在这里插入图片描述

功能需求:商品列表查询

2.3 配置前端控制器

  • web.xml中配置

      <!-- 配置前端控制器 -->
      <servlet>
      	<servlet-name>springmvc</servlet-name>
      	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      	<!-- contextConfigLocation配置springmvc加载的配置文件(配置处理器映射器、适配器等等)
      	如果不配置contextConfigLocation,默认加载的是/WEB-INF/servlet名称/serlvet.xml(springmvc/servlet.xml)
      	 -->
      	<init-param>
      		<param-name>contextConfigLocation</param-name>
      		<param-value>classpath:springmvc.xml</param-value>
      	</init-param>
      </servlet>
      
      <servlet-mapping>
      	<servlet-name>springmvc</servlet-name>
      	<!-- 
      		第一种:*.action,访问以action结尾的由DispatcherServlet进行解析
      		第二种:/,所有访问的地址都由DispatcherServlet进行解析,对于静态文件解析需要配置不让DispatcherServlet解析
      	使用此种方法可以实现RESTful风格
      		第三种:/*,这样配置不对,使用这种配置最终要转发到jsp界面时,
      	仍由DispatcherServlet解析jsp,不能根据jsp页面找到Handler,所以会报错
      	 -->
      	<url-pattern>*.action</url-pattern>
      </servlet-mapping>
    

2.4 处理器适配器

  • 在classpath下的springmvc.xml中配置

    <!-- 处理器适配器 
    所有的处理器适配器都实现HandlerAdapter接口
    -->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" /> 
    
  • 通过查看源代码,此适配器能执行实现controller接口的Handler

    public class SimpleControllerHandlerAdapter implements HandlerAdapter {  
    	 public boolean supports(Object handler) {  
    	     return (handler instanceof Controller);  
    	 }  
    	 ......  
    }
    

2.5 开发Handler

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

    public class ItemsController1 implements Controller{
    	@Override
    	public ModelAndView handleRequest(HttpServletRequest request,
    			HttpServletResponse response) throws Exception {
    		
    		//调用service查找数据库,查询商品列表,这里使用静态数据模拟
    		List<Items> itemsList = new ArrayList<Items>();
    		
    		Items items_1 = new Items();
    		items_1.setName("联想笔记本");  
            items_1.setPrice(6000f);  
            items_1.setDetail("ThinkPad T430 联想笔记本电脑!");  
              
            Items items_2 = new Items();  
            items_2.setName("苹果手机");  
            items_2.setPrice(5000f);  
            items_2.setDetail("iphone6苹果手机!");  
              
            itemsList.add(items_1);  
            itemsList.add(items_2);  
            
            //返回ModelAndView
            ModelAndView modelAndView = new ModelAndView();
            //相当于request的setAttribute,在jsp页面中通过itemsList取数据
            modelAndView.addObject("itemsList", itemsList);
            
            //指定视图
            modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
            
    		return modelAndView;
    	}
    
    }
    

2.6 视图编写

<%@ page language="java" contentType="text/html; charset=UTF-8"  
    pageEncoding="UTF-8"%>  
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>   
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"  prefix="fmt"%>  
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
<html>  
<head>  
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
<title>查询商品列表</title>  
</head>  
<body>   
<form action="${pageContext.request.contextPath }/item/queryItem.action" method="post">  
查询条件:  
<table width="100%" border=1>  
<tr>  
<td><input type="submit" value="查询"/></td>  
</tr>  
</table>  
商品列表:  
<table width="100%" border=1>  
<tr>  
    <td>商品名称</td>  
    <td>商品价格</td>  
    <td>生产日期</td>  
    <td>商品描述</td>  
    <td>操作</td>  
</tr>  
<c:forEach items="${itemsList }" var="item">  
<tr>  
    <td>${item.name }</td>  
    <td>${item.price }</td>  
    <td><fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/></td>  
    <td>${item.detail }</td>  
    <td><a href="${pageContext.request.contextPath }/item/editItem.action?id=${item.id}">修改</a></td>  
</tr>  
</c:forEach>  
</table>  
</form>  
</body>  
</html>  

2.7 配置Handler

  • 将编写Handler在spring容器加载

    <!-- 配置Handler -->
    <bean name="/queryItems.action" class="cn.itcast.ssm.controller.ItemsController1"/>
    

2.8 配置处理器映射器

  • 在classpath下的springmvc.xml中配置

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

2.9 配置视图解析器

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

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

2.10 部署调试

  • 访问地址:http://localhost:8080/SpringMVCStudy/queryItems.action
    在这里插入图片描述
  • 如果地址输错,处理器映射器根据url找不到Handler,报下边的错误。说明url错误。
    在这里插入图片描述
  • 如果处理器映射器根据url找到了Handler,转发的jsp页面找到,报下边的错误,说明jsp页面地址错误了。
  //指定视图里的ViewName可能写错了,不存在你写的那个jsp文件
  modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");  

在这里插入图片描述

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

3.1 非注解的处理器映射器

  • 处理器映射器:
    org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping

    <!-- 配置Handler -->
    <bean id="itemsController1" name="/queryItems.action" class="cn.itcast.ssm.controller.ItemsController1"/>
      
    <!-- 处理器映射器 
    将bean的name作为URL进行查找,需要在配置Handler是指定beanname(就是url)
    --> 
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" /> 
    
  • 另外一个映射器
    org.springframework.web.servlet.handler.SimpleUrlHandlerMapping

    <!--简单url映射  -->  
    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">  
    	<property name="mappings">  
    		<props>  
    			<!-- 对itemsController1进行url映射,url是/queryItems1.action,1个bean可以配多个url -->  
    			<prop key="/queryItems1.action">itemsController1</prop>  
    			<prop key="/queryItems2.action">itemsController1</prop> 
    		</props> 
    	</property>  
    </bean> 
    
  • 多个映射器可以并存,前端控制判断url能让哪个映射器处理,就让哪个映射器处理。

3.2 非注解的处理器适配器

  • org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter
    要求编写的Handler实现Controller接口

    <!-- 处理器适配器 
    所有的处理器适配器都实现HandlerAdapter接口
    -->
    <bean 
      	class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" /> 
    
  • org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter
    要求编写的Handler实现HttpRequestHandler接口

    <!-- 另一个非注解的适配器 -->
    <bean 
    	class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter" />
    
  • ItemsController2

    public class ItemsController1 implements HttpRequestHandler{
    	@Override
    	public void handleRequest(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		
    		//调用service查找数据库,查询商品列表,这里使用静态数据模拟
    		List<Items> itemsList = new ArrayList<Items>();
    		
    		Items items_1 = new Items();
    		items_1.setName("联想笔记本");  
            items_1.setPrice(6000f);  
            items_1.setDetail("ThinkPad T430 联想笔记本电脑!");  
    
            Items items_2 = new Items();  
            items_2.setName("苹果手机");  
            items_2.setPrice(5000f);  
            items_2.setDetail("iphone6苹果手机!");  
            itemsList.add(items_1);  
            itemsList.add(items_2);  
    
    		//设置模型数据
            request.setAttribute("itemsList", itemsList);
            //设置转发的视图
            request.getRequestDispatcher("/WEB-INF/jsp/items/itemsList.jsp").forward(request, response);
            //使用此方法可以通过修改response,设置响应的数据格式,比如json数据
    	}
    }
    
  • 别忘了配置Handler和映射器

          <!-- 配置另外一个Handler -->
          <bean id="itemsController2" class="cn.itcast.ssm.controller.ItemsController1"></bean>
     	<!--简单url映射  -->  
        <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">  
            <property name="mappings">  
                <props>  
                    <!-- 对itemsController1进行url映射,url是/queryItems1.action,1个bean可以配多个url -->  
                    <prop key="/queryItems1.action">itemsController1</prop>  
                    <prop key="/queryItems2.action">itemsController1</prop> 
                    <prop key="/queryItems3.action">itemsController2</prop> 
                </props> 
            </property>  
        </bean> 
    
  • 总的来说,处理器映射器就是根据URL来找Handler,处理器适配器就是按照它要求的规则(handler instanceof XXX接口)去执行Handler

4 DispatcherSerlvet.properties

通过以前咱们写的样例,会发现,多个适配器和多个映射器可以并存但是其实你不在springmvc.xml中配置适配器,也可以正常运行程序。因为在SpringMVC的jar包中含有一个默认配置文件,如果没有在springmvc.xml配置,就默认使用DispatcherSerlvet.properties的配置如图
在这里插入图片描述
前端控制器会从上边的文件中加载处理映射器、适配器、视图解析器等组件,如果不在springmvc.xml中配置,使用默认加载的。

# 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  
  
org.springframework.web.servlet.HandlerMapping=	org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\  
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping  
  
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  

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

  • 注解映射器
    • 在spring3.1之前,使用org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMappin注解映射器。
    • 在spring3.1之后,使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping注解映射器。
  • 注解适配器
    • 在spring3.1之前使用org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter注解适配器。
    • 在spring3.1之后使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter注解适配器。

5.1 配置注解映射器和适配器

<!-- 注解映射器 -->  
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>  
<!-- 注解适配器 -->  
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>  

<!-- 使用mvc的注解驱动mvc:annotation-driven可以代替上边的注解映射器和注解适配器配置 
mvc:annotation-driven默认加载很多参数绑定方法,比如json转换解析器
如果使用mvc:annotation-driven就不用配置上边的RequestMappingHandlerMapping和RequestMappingHandlerAdapter
实际开发使用RequestMappingHandlerAdapter
-->
<!-- <mvc:annotation-driven></mvc:annotation-driven> -->

5.2 开发注解Handler

  • 必须同时使用注解的映射器和注解的适配器,必须配对使用。

    	//使用Controller标识他是一个控制器
    	@Controller
    	public class ItemsController3 {
    	
    		//商品查询列表
    		//@RequestMapping实现queryItems方法和url进行映射,一个方法对应一个url
    		//一般建议将url和方法名写成一样
    		@RequestMapping("/queryItems")
    		public ModelAndView queryItems() throws Exception{
    			
    			//调用service查找数据库,查询商品列表,这里使用静态数据模拟
    			List<Items> itemsList = new ArrayList<Items>();
    			
    			Items items_1 = new Items();
    			items_1.setName("联想笔记本");  
    	        items_1.setPrice(6000f);  
    	        items_1.setDetail("ThinkPad T430 联想笔记本电脑!");  
    	          
    	        Items items_2 = new Items();  
    	        items_2.setName("苹果手机");  
    	        items_2.setPrice(5000f);  
    	        items_2.setDetail("iphone6苹果手机!");  
    	          
    	        itemsList.add(items_1);  
    	        itemsList.add(items_2);  
    		
    	        //返回ModelAndView
    	        ModelAndView modelAndView = new ModelAndView();
    	        //相当于request的setAttribute,在jsp页面中通过itemsList取数据
    	        modelAndView.addObject("itemsList", itemsList);
    	      
    	        //指定视图
    	        modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
    	      
    			return modelAndView;
    		}
    	}
    

5.3 在spring中加载Handler

<!-- 对于注解Handler可以单个进行配置 
    实际开发中建议使用组件扫描
-->
<!-- <bean class="cn.itcast.ssm.controller.ItemsController3"></bean> -->
<!-- 可以扫描controller,service,... 
   这里让组件扫描controller,指定controller的包
-->
<context:component-scan base-package="cn.itcast.ssm.controller"></context:component-scan>

5.4 部署测试

6 源码分析

  • 通过前端控制区源码分析springmvc的执行过程

  • 点开org.springframework.web.servlet.DispatcherServlet,里面有doDiapatch的方法

    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {  
    	HttpServletRequest processedRequest = request;  
    	HandlerExecutionChain mappedHandler = null;  
    	boolean multipartRequestParsed = false;  
    	WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);  
    	try {  
    		ModelAndView mv = null;  
            Exception dispatchException = null;  
    		try {  
    			processedRequest = checkMultipart(request);  
    			multipartRequestParsed = processedRequest != 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; 
                    }
                }  
                if (!mappedHandler.applyPreHandle(processedRequest, response)) { 
                    return;  
                }  
                try {  
                    // Actually invoke the handler.  
                    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());  
                }  
                finally {  
                    if (asyncManager.isConcurrentHandlingStarted()) { 
                        return;  
                    }  
                }  
                applyDefaultViewName(request, mv);  
                mappedHandler.applyPostHandle(processedRequest, response, mv);  
            }  
            catch (Exception ex) {  
                dispatchException = ex;  
            }  
            processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);  
        }  
        catch (Exception ex) {  
            triggerAfterCompletion(processedRequest, response, mappedHandler, ex);  
            } 
        catch (Error err) {  
            triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);  
        }  
        finally {  
            if (asyncManager.isConcurrentHandlingStarted()) { 
                // Instead of postHandle and afterCompletion 
                mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);  
                return;  
            }  
            // Clean up any resources used by a multipart request.
            if (multipartRequestParsed) {  
                cleanupMultipart(processedRequest);  
            }  
        } 
    }
    
    • 第一步:前端控制器接收请求:.action类型的URL通过过滤器进入DispatcherServlet类,调用其doDiapatch()方法

      protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {  
          HttpServletRequest processedRequest = request;  
          HandlerExecutionChain mappedHandler = null;  
          boolean multipartRequestParsed = false;  
      
          WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);  
          ......  
      } 
      
    • 第二步:前端控制器调用处理器映射器查找Handler:在doDiapatch()方法中调用了DispatcherServlet类的getHandler方法

      	HandlerExecutionChain mappedHandler = null;  
      	......  
      	mappedHandler = getHandler(processedRequest, false); 
      
    • 其中getHandler方法:

      @Deprecated  
      protected HandlerExecutionChain getHandler(HttpServletRequest request, boolean cache) throws Exception { 
          return getHandler(request);  
      }  
      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;  
      } 
      
      • 说明映射器根据request当中的URL,找到了Handler,最终返回一个执行器的链(HandlerExecutionChain)。这个链里面有Handler。
    • 第三步:调用处理器适配器执行Handler,得到执行结果ModelAndView

      ModelAndView mv = null;  
      ......  
      mv = ha.handle(processedRequest, response, mappedHandler.getHandler());  
      
    • 第四步:视图渲染,将model数据填充到request域

      • 视图解析,得到view,在doDiapatch()方法中有这一句

        processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
        
        • 其中processDispatchResult方法

          private void processDispatchResult(HttpServletRequest request, 
                                             HttpServletResponse response, 
                                             HandlerExecutionChain mappedHandler, 
                                             ModelAndView mv, 
                                             Exception exception)
              throws Exception {  
              boolean errorView = false;  
              if (exception != null) {  
                  if (exception instanceof ModelAndViewDefiningException) {  
                      logger.debug("ModelAndViewDefiningException encountered", exception);  
                      mv = ((ModelAndViewDefiningException) exception).getModelAndView();
                  }  
                  else {  
                      Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null); 
                      mv = processHandlerException(request, response, handler, exception);  
                      errorView = (mv != null);  
                  }  
              }  
              // Did the handler return a view to render? 
              if (mv != null && !mv.wasCleared()) {  
                  render(mv, request, 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");  
                  }  
              }  
              if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
                  // Concurrent handling started during a forward  
                  return;  
              }  
              if (mappedHandler != null) { 
                  mappedHandler.triggerAfterCompletion(request, response, null);
              }  
          }
          
        • 其中render(mv, request, response);方法中有

          view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);
          
        • 渲染方法:

          view.render(mv.getModelInternal(), request, response); 
          
      • 调用视图渲染方法,将model数据填充到request域

        protected void exposeModelAsRequestAttributes(Map<String, Object> model, HttpServletRequest request) 
            throws Exception {
            //遍历model里面的数据,填充到request域
            for (Map.Entry<String, Object> entry : model.entrySet()) { 
                String modelName = entry.getKey();  
                Object modelValue = entry.getValue();
                if (modelValue != null) {  
                    request.setAttribute(modelName, modelValue);
                    if (logger.isDebugEnabled()) {  
                        logger.debug("Added model object '" 
                                     + modelName 
                                     + "' of type [" 
                                     + modelValue.getClass().getName() 
                                     + "] to request in view with name '" 
                                     + getBeanName() 
                                     + "'"); 
                    }  
                }  
                else {  
                    request.removeAttribute(modelName);  
                    if (logger.isDebugEnabled()) {  
                        logger.debug("Removed model object '" + modelName + 
                                     "' from request in view with name '" + getBeanName() + "'");  
                    }  
                }  
            } 
        }
        

7 入门程序小结

通过入门程序理解springmvc前端控制器、处理器映射器处理器适配器、视图解析器用法。

前端控制器配置:

  • 第一种:*.action,访问以action结尾的由DispatcherServlet进行解析
  • 第二种:/,所有访问的地址都由DispatcherServlet进行解析,对于静态文件解析需要配置不让DispatcherServlet解析,使用此种方法可以实现RESTful风格

处理器映射器:

  • 非注解处理器映射器(了解)
  • 注解的处理器映射器(掌握)
    • 对标记有@Controller类中标识有@RequestMapping的方法进行映射。在@RequestMapping里边定义映射的url。
    • 使用注解映射器不用再xml中配置url和Handler的映射关系。

处理器适配器:

  • 非注解处理器适配器(了解)

  • 注解的处理器适配器(掌握)

    • 注解的处理器映射器和注解的处理器适配器是配对使用的。

      • <mvc:annotation-driven></mvc:annotation-driven>可以代替下面的配置

        <!-- 注解映射器 -->  
        <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>  
        <!-- 注解适配器 -->  
        <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>  
        
    • 实际开发使用:mvc:annotation-driven

视图解析器配置前缀和后缀

<!-- 视图解析器 
解析jsp视图,默认实用jstl标签,classpath下面得有jstl的包
-->       
<bean  
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <!-- 配置jsp路径的前缀 -->
    <property name="prefix" value="/WEB-INF/jsp/"></property>  
    <!-- 配置jsp路径的后缀 -->
    <property name="suffix" value=".jsp"></property>  	
</bean>
  • 程序中不用指定前缀和后缀:

    //指定视图  
    //下边的路径,如果在视图解析器中配置jsp的路径前缀和后缀,修改为items/itemsList  
    //modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp")  
    //下边的路径配置就可以不在程序中指定jsp路径的前缀和后缀  
    modelAndView.setViewName("items/itemsList");
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值