实际上代码是如何运行的呢?
这里建立一个基本工程,工程结构如图:
一、maven引入包
首先用maven相关引用:
1.1 单元测试
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
1.2 msql数据库,也可以是其他
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
1.3 mybatis
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
1.4 spring框架
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
1.5 servlet
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
1.6 jsp
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
1.7 jstl
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
1.8 aop切面编程支持
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.8</version>
</dependency>
1.9 mybatis-spring链接
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.4</version>
</dependency>
整合就是这个样子:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>SpringMVC1</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>servlet</module>
</modules>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.8</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.4</version>
</dependency>
</dependencies>
</project>
二、 相关组件的支持
如图所示:
1:启动工程时,系统加载web.xml
2:当用户输入一个请求时,请求被web.xml中被拦截,转到了springmvc.xml中进行处理
3:由于HandlerMapping有不同的实现类,所以map<url,Handler>映射的规则也不同
4:HandlerMapping根据请求的url找到相应的Handler,返回给DispatcherServlet
5:DispactherServlet请求处理器适配器HandlerAdapter去执行Handler(常称为Controller)
6:处理器适配器(HandlerAdapter)执行Handler
7:Handler执行完毕后会返回给处理器适配器(HandlerAdapter)一个ModelAndView对象
8:HandlerAdapter接收到Handler返回的ModelAndView后,将其返回给前端控制器
9:DispatcherServlet接收到ModelAndView后,会请求视图解析器(View Resolver)对视图进行解析
10:View Resolver根据View信息匹配到相应的视图结果,反馈给DispatcherServlet
11:DispatcherServlet收到View具体的视图后,进行视图渲染,将Model中的数据模型填充到View视图中的request域,生成最终的视图View
12:DispatcherServlet向用户返回请求的结果
通过前面的Spring MVC请求处理流程图可以知道,当请求到达前端控制器DispatcherServlet时,DispatcherServlet会请求处理器映射器(HandlerMapping)寻找相关的Handler对象,打开Spring MVC的源码,可以发现许多种处理器映射器(包括抽象类)。
2.1 处理器映射器HandlerMapping
先在springmvc.xml配置文件中添加处理器映射器:
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
Spring MVC拥有多种处理器映射器,他们都实现了HandlerMapping接口。上面配置的处理器映射器为BeanNameUrlHandlerMapping类,其映射规则是,将bean的name作为url进行查找,需要配置Handler时指定bean的name。
根据Spring MVC的请求流程,DispatcherServlet根据HandlerMapping传来的Handler(或Handler执行链)与配置的处理器适配器HandlerAdapter进行匹配,找到可以处理此Handler(或Handler执行链)类型的HandlerAdapter,该HandlerAdapter将会调用自己的handler方法,利用Java的反射机制去执行具体的Controller方法并获得ModelAndView视图对象。
2.2 处理适配器HandlerAdapter
接下来要在springmvc.xml中配置一个处理器适配器HandlerAdapter。
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
在Spring MVC中,常用的处理器适配器有HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter以及AnnotationMethodHandlerAdapter。
这里配置的处理器是SimpleControllerHandlerAdapter。
SimpleControllerHandlerAdapter适配器支持所有实现了Controller接口的Handler控制器,开发者如果编写了实现Controller接口的控制器,那么SimpleControllerHandlerAdapter适配器会执行Controller的具体方法。
当处理器适配器HandlerAdapter处理了相关的Handler的具体方法之后,Handler会返回一个视图对象ModelAndView
2.3 视图解析器ViewResolver
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"/>
配置了InternalResourceViewResolver视图解析器后,其会根据Handler方法执行之后返回的ModelAndView中的视图的具体位置,来加载相应的界面并绑定反馈数据。
三、 Selvet配置对象关系映射
传统的Selvet的结构
四、对象
class类结构,主要实现get,post方法
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
public class FruitsControllerTest implements Controller{
private FruitsServices fruitsServices= new FruitsServices();
@Override
public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
// TODO Auto-generated method stub
List<Fruits> fruitsList = fruitsServices.queryFruitsList();
ModelAndView mav = new ModelAndView();
//相当于request的setAttribut,在JSP页面中通过fruitsList获取数据
mav.addObject("fruitsList",fruitsList);
//指定视图
mav.setViewName("/WEB-INF/jsp/fruits/fruitsList.jsp");
return mav;
}
}
class FruitsServices{
public List<Fruits> queryFruitsList(){
List<Fruits> fruitsList = new ArrayList<Fruits>();
Fruits apple = new Fruits();
apple.setName("红富士");
apple.setPrice(2.3);
apple.setProducing_area("山东");
Fruits banana = new Fruits();
banana.setName("香蕉");
banana.setPrice(1.5);
banana.setProducing_area("上海");
fruitsList.add(apple);
fruitsList.add(banana);
return fruitsList;
}
}
五、jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!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>Insert title here</title>
</head>
<body>
<H3>新鲜水果</H3>
<table width="300px;"border=1>
<tr>
<td>名称</td>
<td>价格</td>
<td>产地</td>
</tr>
<c:forEach items="${fruitsList}" var ="fruit">
<tr>
<td>${fruit.name}</td>
<td>${fruit.price}</td>
<td>${fruit.producing_area}</td>
</tr>
</c:forEach>
</table>
</body>
</html>
这里使用JSTL的c标签来遍历服务端绑定到前端页面的数据“fruitsList”,并将不同的属性设置在table的不同位置。
六、Bean
由于配置的处理器映射为BeanNameUrlHandlerMapping,在接收到用户的请求时,它会将bean的name作为url进行查找。所以接下来要在springmvc.xml中配置一个可以被url映射的Handler的bean,供处理器映射器查找,该bean的具体配置如下:
<bean name="/queryFruits_test.action" class="cn.com.mvc.controller.FruitsControllerTest"/>
七、 启动工程
启动工程,访问http://localhost:8080/SpringMVC_Test/queryFruits_test.action即可访问。