首页 > 代码库 > SpringMVC(一)

SpringMVC(一)

1 SpringMVC框架

1.1 SpringMVC是什么?

技术分享

  • SpringMVC就是Spring的一个模块,提供web层的解决方案(基于MVC设计架构)。

 

1.2 MVC设计模式在B/S系统中的应用

  • MVC是一个设计模式,在B/S系统中的应用如下图所示。

技术分享

1.3 SpringMVC的框架

技术分享

 

 

SpringMVC的执行步骤:

  • 用户发起request请求,请求到DispatcherServlet前端控制器。
  • DispatcherServlet前端控制器请求HandlerMapping处理器查找Handler。
    • DispatcherServlet:前端口控制器,相当于中央调度器,各个组件都和前端控制器进行交互,降低各个组件之间的耦合。
  • HandlerMapping处理器映射器,根据URL和一些规则(xml配置、注解配置)查找Handler,将Handler返回给DispatcherServlet前端控制器。

  • DispatcherServlet前端控制器调用适配器执行Handler,有了适配器可以在适配器去扩展对不同Handler的执行方式(比如:servlet开发,注解开发)。

  • 适配器执行Handler。
    • Handler是后端处理器。

 

  • Handler执行完成后返回ModelAndView。
    • ModelAndView:SpringMVC的一个对象,对Model和View的一个封装。
  • 适配器将ModelAndView返回DispatcherServlet前端控制器。
  • DispatcherServlet调用视图解析器进行视图解析,解析后生成View。
    • 视图解析器会根据逻辑视图名解析出真正的视图。
    • View:SpringMVC的一个封装对象,提供了很多View,比如jsp、freemaker、PDF等。
  • 视图解决器给前端控制器返回View。
  • 前端控制器调用view的渲染视图的方法,将模型数据填充到request域之中。
  • 前端控制器,向用户响应结果(jsp页面、json数据等等)。

 

【总结】:

  • DispatcherServlet:前端控制器。由SpringMVC提供。
  • HandlerMapping:处理器映射器,由SpringMVC提供。
  • HandlerAdapter:处理器适配器,由SpringMVC提供
  • Handler:处理器,需要程序员开发。
  • ViewResolver:视图解析器,由SpringMVC提供。
  • View视图:真正的视图页面需要程序员编写。

 

  

2 SpringMVC入门程序

 

2.1 建立web项目并导入jar包。

2.2 配置前端控制器(在web.xml文件中)   

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <!-- 前端控制器 -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 加载springmvc的配置文件 -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath*:spring-mvc.xml</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!--
            可以配置/,此工程所有请求全部由SpringMVC解析,此种方式可以实习restful方式,需要特殊处理,对静态文件不能由SpringMVC解析
            可以配置*.do或*.action等等,所有请求的URL的扩展名为.do或.action之类,由SpringMVC解析
            不可以配置/*,如果/*,返回的jsp也有SpringMVC解析
        -->
        <url-pattern>*.action</url-pattern>
    </servlet-mapping>


</web-app>

2.3 新建spring-mvc.xml(配置处理器映射器、处理器适配器和视图解析器)

2.3.1 配置处理器映射器

    <!--
        处理器映射器
        根据URL(xxx.action)匹配spring容器bean的name,找到对应的Handler
     -->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>

2.3.2 配置处理器适配器

 <!--
        处理器适配器
        
    -->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>

我们查看此处理器适配器的源码:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.web.servlet.mvc;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.ModelAndView;

public class SimpleControllerHandlerAdapter implements HandlerAdapter {
    public SimpleControllerHandlerAdapter() {
    }

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

    public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return ((Controller)handler).handleRequest(request, response);
    }

    public long getLastModified(HttpServletRequest request, Object handler) {
        return handler instanceof LastModified?((LastModified)handler).getLastModified(request):-1L;
    }
}

我们看到下面的代码

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

就知道此种适配器,要求程序员编写的handler要实现Controller接口。

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.web.servlet.mvc;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;

public interface Controller {
    ModelAndView handleRequest(HttpServletRequest var1, HttpServletResponse var2) throws Exception;
}

那么,再看此种处理器适配器的如下代码:

 public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return ((Controller)handler).handleRequest(request, response);

就应该知道,一旦我们编写的Handler(也可以称为Controller)实现了Controller接口,那么此种适配器就可以执行我们编写的Handler了。

注意】SpringMVC会根据HandlerMapping接口(或其子接口或实现类)判断是否是处理器映射器,会根据HandlerAdapte(或其子接口或实现类)接口判断是否是处理器适配器

    

2.3.3配置视图解析器

<!-- 视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 配置前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!-- 配置后缀 -->
        <property name="suffix" value=".jsp"/>
    </bean>

 

2.4 编写Handler

2.4.1 新建Item.java

package cn.vo;
import
java.util.Date; public class Items { private Integer id; private String name; private Float price; private String pic; private Date createtime; private String detail; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name == null ? null : name.trim(); } public Float getPrice() { return price; } public void setPrice(Float price) { this.price = price; } public String getPic() { return pic; } public void setPic(String pic) { this.pic = pic == null ? null : pic.trim(); } public Date getCreatetime() { return createtime; } public void setCreatetime(Date createtime) { this.createtime = createtime; } public String getDetail() { return detail; } public void setDetail(String detail) { this.detail = detail == null ? null : detail.trim(); } }

2.4.2 新建ItemController.java

package cn.action;

import cn.vo.Items;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 * 描述:
 */

public class ItemController implements Controller {
    @Override
    public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws Exception {

        List<Items> itemsList = new ArrayList<Items>();

        Items items_1 = new Items();
        items_1.setName("联想笔记本");
        items_1.setPrice(6000f);
        items_1.setCreatetime(new Date());
        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 = new ModelAndView();
        modelAndView.addObject("itemsList",itemsList);
        modelAndView.setViewName("itemsList");

        return modelAndView;
    }
}

2.5 在spring-mvc.xml文件中配置Handler

 <!--
        配置处理器
    -->
    <bean  name="/itemList.action" class="cn.action.ItemController"></bean>

 

2.6 在WEB-INF下新建jsp目录和itemList.jsp文件

<%@ 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>

 

3 注解的映射器和适配器

3.1 DispatcherServlet.properties

技术分享

  • DispatcherServlet前端控制器加载DispatcherServlet.properties配置文件,从而默认加载各个组件。如果在spring-mvc.xml中配置了处理器映射器和适配器,DispatcherServlet按照Spring-mvc.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

3.2 注解映射器

  • 在Spring3之前默认的注解映射器如下图所示,当然在Spring3之后此注解映射器已经过期。

技术分享

  • Spring3之后的注解映射器,如下图所示。

技术分享

  • 使用RequestMappingHandlerMapping需要在Handler中使用@Controller标识此类事一个控制器,使用@requestMapping指定Handler方法所对应的URL。

3.3 注解适配器

  • 在Spring3之前的默认注解适配器如下图所示,当然,现在已经过期了。

技术分享

  • Spring3之后默认的注解适配器

技术分享

  • RequestMappingHandlerAdapter不要求Handler实现任何接口,它需要和RequestMappingHandlerAdapter注解映射器配对使用,主要解析Handler方法中的形参。

 

3.4 修改上面的代码,该为注解方式

3.4.1 sping-mvc.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 ">

    <context:component-scan base-package="cn.action"/>


    <!-- 视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 配置前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!-- 配置后缀 -->
        <property name="suffix" value=".jsp"/>
    </bean>



</beans>

 

3.4.2 控制器

package cn.action;

import cn.vo.Items;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 * 描述:
 */
@Controller
public class ItemController {

    @RequestMapping(value = "/itemsList.action")
    public String list(Model model){

        List<Items> itemsList = new ArrayList<Items>();

        Items items_1 = new Items();
        items_1.setName("联想笔记本");
        items_1.setPrice(6000f);
        items_1.setCreatetime(new Date());
        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);

        model.addAttribute("itemsList",itemsList);
        return "itemsList";
    }



}

 

4 入门程序小结

  • DispatcherServlet:前端控制器,相当于中央调度器,可以降低各个组件之间的耦合。
  • HandlerMapping:处理器映射器,负责根据URL查找Handler。
  • HandlerAdapter:处理器适配器,负责跟进适配器要求的规则去执行处理器。可以通过扩展适配器,让其支持不同的handler。
  • viewRosolver:视图解析器,根据逻辑视图名解析成真正的视图。

 

  • DispatcherServlet通过HandlerMapping查找Handler

技术分享

技术分享

技术分享

 

 技术分享

  • DispatcherServlet通过适配器去执行Handler,得到ModelAndView

技术分享

 

 

  •  视图解析

技术分享

技术分享

 

 技术分享

  • 视图渲染

技术分享

技术分享

技术分享

 

SpringMVC(一)