Spring MVC的处理步骤是怎样的

1、曾经的王者——Servlet

在笔者刚接触到使用Java进行Web开发的时候,Spring MVC远没有今天这么流行,君不见曾经的王者Servlet繁盛一时的场面。现在回想起来,使用Servlet进行开发虽然不像现在这么容易,好多的事情需要自己做,但是Servlet使得开发的逻辑变得十分清晰,尤其是在Servlet与jsp很好的承担了各自的角色之后,再加上mvc分层思想的流行。编写Web应用程序在那时是一件快乐而又简单的事情。

实际上Servlet做的事情并不是很多,笔者觉得Servlet想要完成的就是统一请求的接受、处理与响应的流程。

网络编程中绕不开的一个东东想必不用说大家也猜得到,那就是Socket。但是网络需要传输的话是很复杂的,首先需要遵循一定的协议,现在我们一般使用Http与Https传输数据,而Socket就是在一些网络协议之上,屏蔽了底层协议的细节,为使用者提供一个统一的api。但是Servlet认为Socket做的还不够,或者说我们还要进行相应的处理。于是Servlet(就HttpServlet来说),他将网络中的请求报文进行封装转化成为了Request表示,在Http通信过程之中就是HttpServletRequest,而将服务端处理请求后返回的响应统一的封装为了HttpServletResponse对象。

这样做的好处是什么呢?

我们作为开发者,不必再去做一些处理网络请求与响应的繁琐之事,而只需要关注于我们的业务逻辑开发。

大家有没有发现,每一次框架效率的提升很多时候都是在将最最重要的业务逻辑与其他任务尽可能完全的分离开,使我们总可以全身心的投入到业务逻辑的开发之中,Spring AOP是不是就是一个很好的佐证呢!

那么Servlet如何使用呢?

没有Servlet使用经历的同学可以听我简单的说一说:

 1.  首先我们通常要编写一个自己的Servlet然后继承自HttpServlet,然后重写其doGet()与doPost()方法。这两个方法都会将HttpServletRequest与HttpServletResponse作为参数传递进去,然后我们从Request中提取前端传来的参数,在相应的doXXX方法内调用事先编写好的Service接口,Dao接口即可将数据准备好放置到Response中并跳转到指定的页面即可,跳转的方式可以选择转发或者重定向。

2.  Servlet使用的是模板方法的设计模式,在Servlet顶层将会调用service方法,该方法会构造HttpServletRequest与HttpServletResponse对象作为参数调用子类重写的doXXX()方法。然后返回请求。

3.  最后我们需要将我们编写的自定义Servlet注册到web.xml中,在web.xml中配置servlet-mapping来为该servlet指定处理哪些请求。

Servlet的使用就是这么简单!事实上,在很长的一段时间内他的流行也得益于他的简单易用易上手。


  1. <web-app xmlns="http://java.sun.com/xml/ns/j2ee"  
  2.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"  
  4.     version="2.4">  
  5.     <servlet>  
  6.             <servlet-name>ShoppingServlet</servlet-name>  
  7.             <servlet-class>com.myTest.ShoppingServlet</servlet-class>  
  8.     </servlet>  
  9.     <servlet-mapping>  
  10.             <servlet-name>ShoppingServlet</servlet-name>  
  11.             <url-pattern>/shop/ShoppingServlet</url-pattern>  
  12.     </servlet-mapping>  
  13. </web-app> 

2、想要更进一步

当我们使用Servlet来进行业务逻辑开发的时候,时常会感觉到爽歪歪,但是爽歪歪的同时也感觉到有那么一点点不适。不适的地方主要有以下几点:

  •  每个Servlet只能处理一个请求,这样当系统比较大,业务比较复杂的时候可能会存在成百上千的Servlet,找起来都眼花。
  •  每次我们都需要手动的从Request中获取请求参数,然后封装成我们想要的对象,这其中可能还要对参数进行校验,在调用业务逻辑层获取到数据之后,我们还要手动的设置到响应中,同时手动的选择转发或者重定向进行跳转。
  •  我们的请求的url是硬配置到web.xml中的,缺乏灵活性,如果可以动态的配置这种请求url与处理的对应关系就好了。
  •  我们的Servlet与前端的渲染框架紧耦合在一块,这样当前端换一种显示技术的时候就需要改动较大的代码,如果能把数据的处理与数据的显示分离,让其松散耦合就更好了。

带着这些思考,能不能进一步的来抽离业务逻辑的开发呢?

在早期的时候笔者也曾进行一些尝试,其大概思路就是编写一个BaseServlet,然后我们自己定义的Servlet继承自BaseServlet,前端的请求需要指定Servlet的哪个方法进行处理,这样请求的时候将需要带上一个method参数,例如这样:

 

在BaseServlet中将提取该参数信息,并使用反射的方法调用子类的该方法,子类方法统一返回String类型的结果,代表要返回的逻辑视图名,也就是要跳转的路径,然后父类拿到结果,使用重定向或者转发进行跳转。

说到这里,有小伙伴肯定不耐烦了,明明是讲Spring MVC的,到现在连个Spring MVC的影都还没见,全是在讲Servlet。先别着急,理解这些对我们理解Spring MVC有很大的帮助,请往下看

说到这里,其实是想说,如果我们想要在Servlet上更进一步,想要进一步的将业务逻辑与其他工作相分离,那么就需要在Servlet之上,构建一个事无巨细,任劳任怨,神通过大,…(额想不起来。。。)的超级Servlet,来为我们这些工作,我们暂且把这个Servlet叫做超级牛逼Servlet。而开发Spring的那些人是啥大佬,我们能想到这些,他们能想不到?于是他们动手开发了这个超级牛逼Servlet,并正式命名为DispatcherServlet。

3、Spring MVC——两级控制器方式

接下来我们就要正式的开始Spring MVC之旅了,通过前面的了解,我们知道Spring MVC把那个超级牛逼Servlet叫做DispatcherServlet,这个Servlet可以说为简化我们的开发操碎了心,我们称之为_前端控制器。现在我们不禁思考,前面我们写的BaseServlet对应现在的超级牛逼Servlet(DispatcherServlet)。那么定义我们业务逻辑的自定义Servlet叫啥呢?Spring MVC管定义我们的业务逻辑处理的类叫做Handler,只不过他不再是一个Servlet了,而是一个普普通通的类,这也很好理解,毕竟DispatcherServlet做了太多,而且那么牛逼,完全可以像对待Servlet一样对待一个普通的类,而这个Handler就叫做次级控制器_。

这里可能有小伙伴持反对意见了,有的书上说了Spring MVC的次级控制器叫Controller,不是Handler。

其实Spring MVC的次级控制器确实是叫Handler,只不过Hander是一个抽象的,而Spring MVC选择使用Controller来实现Handler,讲到这里,你觉得我们能不能自定义一个Handler实现,叫做Lellortnoc呢?答案当然是可以的!就好像List是一个抽象的接口,而List的实现有ArrayList,LinkedList一样。

4、DispatcherServlet——前端控制器

DispatcherServlet是整个Spring MVC的核心,超级牛逼Servlet这个荣誉称号他是名副其实。DispatcherServlet和其家族成员兄弟一起完成了很多的工作,包括请求参数的自动绑定,参数的自动校验,请求url的自动匹配,逻辑视图名到真实页面的跳转,数据获取与数据渲染显示的分离等等。。。在此过程中他更像是一个指挥家,有条不紊的指挥着请求不断的向前处理,并最终完成服务端的响应数据。

想要了解具体DispatcherServlet都是怎么指挥的,那就继续往下看吧!推荐:250期面试题汇总

5、HandlerMapper——请求映射专家

想想我们在使用Servlet编写代码的时候,请求的映射工作是交给了web.xml。但是现在Spring MVC采用了两级控制器的方式,就必须解决这个棘手的问题。

【声明】:芜湖站长网内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。

相关文章