servlet是什么
好像在使用了SpringBoot后,或者说Spring后,程序员好像越来越难接触到servlet这个东西了,很多人以为隐藏在重重框架后的servlet是个超级复杂的洪水猛兽,但是并不是这样的。事实上,servlet就是一个Java接口,interface! 打开idea,ctrl + shift + n,搜索servlet,就可以看到是一个只有5个方法的interface!
public interface Servlet { |
所谓接口,无非是为了规范。那么对于那些实现了servlet接口的类来说呢?他们就可以处理网络请求的吗?当然是不可以的!servlet并不与客户端直接打交道,真正和客户端打交道的东西是tomcat容器,tomcat监听了端口,每过来一个http请求,tomcat根据http请求的url,将请求转发到tomcat中的对应的servlet容器中,然后servlet处理业务逻辑后返回一个response对象,tomcat再将这个response返回给客户端。
框架中的servlet
其实对于框架的使用者来说,许多人其实完全不知道自己写的类,什么时候被谁调用了,你甚至没有看到这个类被new以下,但是类里面的代码就是执行了。你好像就是配了个.xml文件,然后按了下Run/Debug按钮,项目就跑了起来。
其实没什么复杂的,这些东西,抽象的讲其实就是——注入和回调,你自己的代码里或许没有一个显式入口,但是tomcat中有个main方法,假设是这样的
我们只需要写个xml,框架机会解析xml创建实例,通过接口注入实例到合适的位置来执行我们的代码,其实并不很难懂。
实现一个Servlet
对于servlet接口来说,你可以发现你如果想直接实现Servlet接口,似乎很难,因为service()方法中的两个参数,一个是Request,Response。这两个东西怎么写嘛!前面说到servlet的请求其实是由tomcat传入的,所以其实tomcat会将将这两个请求封装成对象传给我们。我们往下看,servlet包中还有一个抽象类实现了servlet接口,叫做GenericServlet,但是点进源码一看,里面关于servlet接口的方法都是抽象的。所以再往下看,有一个叫做HttpServlet的抽象类继承了GenericServlet,里面也完善了servlet接口的函数。所以我们要实现一个servlet只需要继承HttpServlet方法就可以了。但是我们要重写HttpServlet里的方法也是有讲究的。不妨先看看里面service方法的源码
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { |
可以看到他会根据你请求方式的不同,来调用不同的函数,拿get请求时候的方法举例子,doGet()方法的源码是这样的
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { |
意思就是要是http/1.1的话,返回405,否则返回400,反正就是不管怎么样都是失败。但是这也正常啊,因为这段东西其实属于业务逻辑范畴,所以对于父类来说,父类无法知道业务逻辑,所以写一个模板方法,具体业务逻辑抽象成方法让子类来实现。这其实就是设计模式中的模板方法模式。