SpringMVC 的初理解
项目中用到了jetty,springboot两种构建服务器的方式,jetty是一种嵌入式的方式,部署启动都很灵活,springboot最大的优点就是很多配置文件都自己集成好了,虽然用了这么多好的框架,但是我最近又迷茫了,这些框架到底是什么?怎么处理的?因此我又开始翻看了Tomcat,结合之前的学习和一些博客文章,记录一下,加深理解。
在写SpringMVC的时候,其实我们就是在写一个servlet。Tomcat即是一个HTTP服务器,也是一个servlet容器,主要目的就是包装servlet,并对请求响应相应的servlet,纯servlet的web应用似乎很好理解Tomcat是如何装载servlet的。
1、什么是servlet?
Servlet是sun公司提供的一门用于开发动态web资源的技术。
2、如何编写一个servlet?
2.1、编写一个Java类,实现HttpServlet接口,HttpServlet是在原有Servlet接口上添加了一些与HTTP协议处理方法,它比Servlet接口的功能更为强大。该类实现了Servlet的service方法,在方法体内判定了调用的是get,post,put,delete方法。如为GET请求,则调用HttpServlet的doGet方法,如为Post请求,则调用doPost方法。用户只要根据自己的需求重写doGet,doPost方法就可以了。
2.2、把开发好的Java类部署到web服务器中。
2.3、用浏览器发送请求就可以。这里我用postman发送一个请求。
请求的地址:localhost:8080/ServletStudy/servlet/ServletDemo
1 2 3 4 5 6 7 8 9 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" > <HTML> <HEAD> <TITLE>A Servlet</TITLE> </HEAD> <BODY> This is class servlet.study.ServletDemo, using the GET method </BODY> </HTML> |
如果是浏览器发送的请求,那么浏览器就会解析上面这段html
3、下面是一个servlet的实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?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" version= "3.0" metadata-complete= "true" > <servlet-name>list</servlet-name> <!-- 告诉容器,类完整的名字 包名.类名 --> <servlet- class >web02.ListEmpServlet1</servlet- class > </servlet> <servlet-mapping> <servlet-name>list</servlet-name> <url-pattern>/list</url-pattern> </servlet-mapping> </web-app> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | package web02; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ListEmpServlet extends HttpServlet { public void service(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{ response.setContentType( "text/html;charset=utf-8" ); PrintWriter out=response.getWriter(); Connection conn= null ; try { Class.forName( "oracle.jdbc.driver.OracleDriver" ); try { conn=DriverManager.getConnection( "jdbc:oracle:thin:@10.10.141.151:1521:orcl" , "wwj" , "Admin@1234" ); out.println( "<table width='60%' border ='1' cellpadding='0' cellspacing='0'>" ); out.println( "<tr><td>姓名</td><td>薪水</td><td>年龄</td>" + "</tr>" ); String sql=( "SELECT name,salary,age from servlet_wu" ); PreparedStatement stat=conn.prepareStatement(sql); ResultSet rst=stat.executeQuery(); while (rst.next()) { String uname=rst.getString( "name" ); Double salary=rst.getDouble( "salary" ); int age=rst.getInt( "age" ); out.println( "<tr>" + "<td>" +uname + "</td><td>" +salary + "</td><td>" +age + "</td></tr>" ); } out.println( "</table>" ); //out.println("添加员工成功");//这句话在重定向之后会被清除,想要输出 //需要用脚本JS response.sendRedirect( "list" ); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (ClassNotFoundException e) { // 记日志 e.printStackTrace(); } out.close(); //关流或者servlet关闭后,服务器就会从响应对象中 } } |
看到这个实例可以清楚的看到,一个servlet里面包括了很多,主要有:请求数据的解析,连接数据库,解析数据,返回给浏览器。一个两个还好维护,也很轻松,但是如果有十个,百个,千个呢?不敢想象。为了解决这个问题,MVC思想被应用过来,解救了广大的程序猿。
4、spring web mvc的原理图如下。
加载过程原理分析:
整个MVC的中心是dispatcherServlet,它处理了controller类的加载,请求地址与controller的映射,viewResolver类的处理,就是所谓的MVC。
1 2 3 4 5 6 7 8 9 10 11 | protected void initStrategies(ApplicationContext context) { initMultipartResolver(context); initLocaleResolver(context); initThemeResolver(context); initHandlerMappings(context); initHandlerAdapters(context); initHandlerExceptionResolvers(context); initRequestToViewNameTranslator(context); initViewResolvers(context); initFlashMapManager(context); } |
这些都是初始化的时候需要做的事。
当用户的请求过来之后,具体流程步骤如下:
1、 首先用户发送请求——>DispatcherServlet,前端控制器收到请求后委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制;
2、 DispatcherServlet——>HandlerMapping。ApplicationContext.xml中id=handlermapping类会将请求的地址与控制器对应的map,然后DispatcherServlet类会把请求地址与servlet对应上。加载applicationContext.xml中的bean对应的类,处理viewresolver。
3、 HandlerAdapter——>处理器功能处理方法的调用,HandlerAdapter将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView对象(包含模型数据、逻辑视图名);
4、 ModelAndView的逻辑视图名——> ViewResolver, ViewResolver将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;
5、 View——>渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构,因此很容易支持其他视图技术;
6、返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。
下面是我之前自己写的一个例子:
web.xml的配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <?xml version= "1.0" encoding= "UTF-8" ?> <web-app version= "3.0" xmlns= "http://java.sun.com/xml/ns/javaee" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" > <servlet> <servlet-name>springmvc</servlet-name> <servlet- class >org.springframework.web.servlet.DispatcherServlet</servlet- class > <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContextmvc.xml</param-value> </init-param> <!-- 启动tomcat之后优先启动 --> <load-on-startup> 1 </load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>*. do </url-pattern> </servlet-mapping> </web-app> |
applicationContext.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | <?xml version= "1.0" encoding= "UTF-8" ?> <beans xmlns= "http://www.springframework.org/schema/beans" xmlns:context= "http://www.springframework.org/schema/context" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xmlns:aop= "http://www.springframework.org/schema/aop" xmlns:tx= "http://www.springframework.org/schema/tx" xmlns:p= "http://www.springframework.org/schema/p" xmlns:util= "http://www.springframework.org/schema/util" xmlns:jdbc= "http://www.springframework.org/schema/jdbc" xmlns:cache= "http://www.springframework.org/schema/cache" xsi:schemaLocation=" http: //www.springframework.org/schema/context http: //www.springframework.org/schema/context/spring-context.xsd http: //www.springframework.org/schema/beans http: //www.springframework.org/schema/beans/spring-beans.xsd http: //www.springframework.org/schema/tx http: //www.springframework.org/schema/tx/spring-tx.xsd http: //www.springframework.org/schema/jdbc http: //www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd http: //www.springframework.org/schema/cache http: //www.springframework.org/schema/cache/spring-cache-3.1.xsd http: //www.springframework.org/schema/aop http: //www.springframework.org/schema/aop/spring-aop.xsd http: //www.springframework.org/schema/util http: //www.springframework.org/schema/util/spring-util.xsd"> <!-- 配置handlerMapping --> <bean id= "handlermapping" class = "org.springframework.web.servlet.handler.SimpleUrlHandlerMapping" > <!-- 请求和controller对应的关系 --> <property name= "mappings" > <props> <prop key= "/list.do" >listController</prop> <prop key= "/add.do" >addController</prop> <prop key= "/modify.do" >modifyController</prop> <prop key= "/delete.do" >deleteController</prop> <prop key= "/update.do" >updateController</prop> </props> </property> </bean> <!-- 配置controller --> <bean id= "listController" class = "springMVCmybatis.listController" > </bean> <bean id= "addController" class = "springMVCmybatis.addController" > </bean> <bean id= "modifyController" class = "springMVCmybatis.modifyController" > </bean> <bean id= "deleteController" class = "springMVCmybatis.deleteController" > </bean> <bean id= "updateController" class = "springMVCmybatis.updateController" > </bean> <!-- 配置viewResolver --> <bean id= "viewresolver" class = "org.springframework.web.servlet.view.InternalResourceViewResolver" > <property name= "prefix" value= "/WEB-INF/" > </property> <property name= "suffix" value= ".jsp" > </property> </bean> </beans> |
附言:
1、如果你看不懂springmvc的代码过程,可以先看看jetty的,有助于理解。
2、由于本人水平有限,有些地方写的模棱两可,后面再写详细点。
参考博客:
1、http://blog.csdn.net/tiantiandjava/article/details/47663853
2、http://jinnianshilongnian.iteye.com/blog/1594806
3、http://www.cnblogs.com/xdp-gacl/p/3760336.html
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步