咱们最初的javaSE部分学习后,基本算是入门了,也熟悉了Java的语法和一些经常使用API,而后再深刻到数据库操做、WEB程序开发,渐渐会接触到JDBC、Servlet/Jsp之类的知识,期间可能会接触一两个关系型数据库,例如MySQL/Oracle等等。像前面的MyBatis部分,主要是针对JDBC的进一步封装,使得更适用于实际项目开发过程,可是JDBC、MyBatis或者Hibernate都是针对持久层数据库操做,例如查询、更新记录等等,咱们开发程序最终的展示对象是用户,而用户操做程序每每用的是什么?各类各样的浏览器,而不是经过咱们后台的这些测试代码,用户看不懂代码,也不须要懂。用户只须要点击、须要输入,好比点击一个连接,跳转到一个新页面,页面中的部分数据都是从数据库中查询获取的;又或者是输入一段文本,点击提交按钮,更新的是数据库中的记录。咱们要理清的是,这些页面的操做指令是怎样传递到后台服务器,而后访问到数据库的;还有数据库的数据是怎么从后台又传回前端,怎样显示到页面上的?html
若是有学习过Servlet/Jsp相关内容,应该会对上面的问题多少有些理解。首先回顾下什么是Servlet,Servlet是运行在咱们服务器上的Java程序,做用于中间层,即客户端请求和服务器之间,咱们发送请求,控制数据库、业务逻辑、作出响应,返回前端页面数据等等均可以经过其实现。Servlet的生命周期:1.初始化调用init()方法,2.处理客户端请求调用service()方法,3.结束程序调用destroy方法,4.最后垃圾回收。JSP本质上也是Servlet,项目启动,Web容器将JSP的代码编译成JVM可以识别的java类即Servlet。Jsp重点偏向于页面的展现,应用html、CSS、JavaScript等前端技术在这里都不成问题,而Servlet更倾向于后台的业务逻辑、控制转发等等。前端
SpringMVC是在Servlet基础上进一步封装开发的一套WEB层框架,因此若是能深刻理清Servlet的相关内容,那么很容易就能够上手SpringMVC,下面咱们先简单回顾一下以前Servlet的实现过程。java
新建一个普通web工程或者maven web工程,经过继承HttpServlet,建立咱们自定义的Servlet,以下所示web
package com.mmm.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class MyServletA extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //请求转发,至关于一次请求 req.getRequestDispatcher("/a.jsp").forward(req, resp); //响应重定向,至关于二次请求,前一次请求设置的属性值在页面中将没法获取到 //resp.sendRedirect("./a.jsp"); //这里每每还要经过持久层对象访问数据库,获取或者更新数据 //获取到的数据经过设置属性,而后在前端Jsp页面能够经过el表达式之类的方法拿到而后渲染样式展现出来 } }
这里的/a.jsp,表明Jsp页面路径,为web文件根目录下例如webapp下,因此咱们在webapp下简单建立a.jsp以下spring
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!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>a.jsp</title> </head> <body> 这是a.jsp </body> </html>
而后在web文件夹下WEB-INF文件夹下web.xml中<web-app></web-app>节点内添加以下内容数据库
<servlet> <servlet-name>MyServletA</servlet-name> <servlet-class>com.mmm.servlet.MyServletA</servlet-class> </servlet> <servlet-mapping> <servlet-name>MyServletA</servlet-name> <url-pattern>/a.do</url-pattern> </servlet-mapping>
这里的<servlet-name>的值在<servlet>和<servlet-mapping>中要保持一致,<servlet-class>即为咱们前面自定义的Servlet全名(含包名),<url-pattern>用于匹配咱们在地址栏输入的url地址。例如这里经过localhost:8080/servlet-web/a.do就能够匹配到该Servlet,从而运行到该Servlet中的相关方法,这里会请求转发到a.jsp,以下图所示。浏览器
上面为一个最基本的从前端http请求到后台服务器,运行Servlet后,返回前端视图的过程。可是实际状况下,前端的请求不会是这样简单拿回一个静态无数据的页面,也不会只有一个,举个例子,若是上面a.do对应一个增长一条商品数据的操做,即在咱们自定义的MyServlet中doPost()方法里执行添加操做,那么若是还有删改查操做,按照这里的路子,咱们须要再定义MyServletB、MyServletC、MyServletD,而后web.xml添加3段对应的Servlet节点定义,再继续拓展,咱们不止对商品进行增删改查,还有员工、销售记录等等进行操做,这样下去,咱们得定义和配置多少个Servlet,有的人想到办法,例如商品的操做路径匹配都是a.do,而后加个参数判断,及路径后加上?action=add或者?action=del等等,这样同一类对象的操做咱们将其统一匹配到同一个Servlet,在Servlet的方法内部再去根据具体的action操做类型去判断到底要执行哪一种操做(运行哪段业务逻辑)。spring-mvc
SpirngMVC更是将这种思想进化到了极致,咱们在web,xml只定义有且只有一个Servlet,这个Servlet能匹配到全部的正常请求,而后能够根据路径精确解析到具体的执行某个类的某个方法,这里的类即控制层Controller,例如一个商品的相关操做,咱们定义一个商品Controller类,类中定义各类操做方法,须要访问数据库的话,每每是经过Service层对象去调用持久层的代码实现数据库操做。下面就实例一段单独经过SpringMVC来实现中间控制层效果的小案例。服务器
为了方便管理jar包,这里咱们能够新建一个maven web项目,pom依赖可参考前面的环境搭建篇,这里同Servlet对比,咱们仅须要一个Java类也就是上面提到的controller,而后是一个指定路径下的jsp文件,最后稍微修改一下web.xml,这三步便可简单过一遍SpringMVC的基本运行过程。下面分别详细写出这三步的内容。mvc
package com.mmm.web; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("demo") public class DemoController { @RequestMapping(value="/toPage") public String toPage() { return "page"; } }
从上往下,首先@Controller注解属于Spring系列组件bean注解之一,对应web表现层的组件,相似的还有表明业务逻辑层的@Service,表明数据库访问层的@Repositoty,通用组件@Component等等,实际项目中,层与层之间类对象还会相互调用,基于Spring容器的IOC及依赖注入,咱们又还会接触到@Autowired,@Autowired等等注解。在这里咱们能够简单理解为经过@Controller注解,Spring会识别并实例化这个bean,这个类对象的建立和管理将交由Spring容器去控制。
而后@RequestMapping("demo"),看英文单词意思应该不难理解,Request请求,Mapping映射,请求映射,经过咱们客户端例如浏览器那边过来的http请求,前面咱们用过的Servlet会经过配置url匹配到访问路径从而匹配到相应的Servlet中,而在这里相似,SpringMVC会根据咱们的访问路径匹配到相应的Contoller中的相应方法,是的,这里还会进一步精确匹配到方法。下面@RequestMapping(value="/toPage")即方法名的映射,例如这里把类和方法的映射名组合起来即为demo/toPage,在本例中,咱们经过localhost:8080/spring-mvc/demo/toPage,便可匹配到这个DemoController的toPage方法中执行。
能够看到方法的返回值是String字符串类型,这里能够理解为用于获取视图页面路径。下面结合Spring MVC配置文件讲解。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> <!-- 自动扫描开启 --> <context:component-scan base-package="com.mmm.web" /> <mvc:annotation-driven/> <!-- Spring MVC视图解析配置--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/" /> <property name="suffix" value=".jsp" /> </bean> </beans>
这里的<context:component-scan base-package="com.mmm.web" />即用于Spring扫描识别bean注解,例如刚刚讲到的@Controller,而<mvc:annotation-driven/>则用于扫描SpringMVC相关特定注解,例如这里@RequestMapping等等。
下面的视图解析配置即结合刚刚上面讲到的视图页面路径,prefix和suffix分别为前缀和后缀的意思,结合前面的controller中方法,即页面请求转发路径的统一先后缀,前面controller中方法的返回值为"page",那么组合先后缀,即为/WEB-INF/views/page.jsp,而这个路径对应哪里,以下图所示。
因此咱们要在这里建立一个jsp文件,views文件夹也是。
最后在web.xml中加入以下内容
<servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:/application-mvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
咱们会发现这里也是配置的Servlet,即org.springframework.web.servlet.DispatcherServlet,只不过只配置了这单独一个,映射路径匹配通用请求,同时init-param设置初始参数即咱们SpringMVC配置文件路径。这样一来,咱们请求都会被SpringMVC系列组件接受、解析路径、分配到相应的Controller的相应方法。
上面步骤结束后,咱们发布项目并启动Tomcat服务器,在浏览器地址栏输入http://localhost/spring-mvc/demo/toPage,看到以下页面,即为成功
经过上面基础的实例,咱们能一步步理解从Servlet到web框架SpringMVC的使用,实际开发中一样遵循这些基本规则,只不过事更多的业务逻辑、视图文件等等,好比这里讲到页面跳转中的请求转发,那么是否相似Servlet还有响应重定向,还有,Controller中方法咱们不必定是跳转到页面,也能够直接传递JSON数据返回前端,以及咱们前面学习到的MyBatis封装持久层,那么咱们在这里怎么与持久层链接起来去访问数据库查询或者更新数据,还有到底什么是业务逻辑,等等这些都是咱们须要考虑的问题,后面准备分别以具体实例展开说明,欢迎一块儿探讨。