GenericServlet HttpServlet,Blade Web框架处理分发逻辑

    xiaoxiao2021-03-25  80

    GenericServlet

    GenericServlet定义了一个通用的,无关协议的的Servlet。如果要在Web应用中使用Http进行Servlet通信,请扩展HttpServlet(即继承HttpServlet)

    GenericServlet是个抽象类,不能直接进行实例化,必须给出子类才能实例化。

    其service方法是个抽象方法,即它把处理请求的任务交给了子类。子类必须实现该方法。 总得来看,它给出了设计servlet的一些骨架,定义了servlet生命周期,还有一些得到名字、配置、初始化参数的方法,其设计的是和应用层协议无关的,也就是说你有可能用非http协议实现它(其实目前Java Servlet还是只有Http一种)。

    就是由于其定义的生命的周期哦,GenericServlet主要由Web容器进行触发,传递给我们浏览器请求的参数进行了处理哦。

    其实现了ServletConfig的接口,但是其也有一个ServletConfig的Field,所有的实现ServletConfig接口的方法都是由当前这个变量进行处理哦。 private transient ServletConfig config;

    Called by the servlet container to indicate to a servlet that the servlet is being placed into service.ServletConfig,this object is from the servlet container for later use. ServletConfig这个很有用的,是被容器进行调用的哦!这里使用了模板方法模式,定义了一定的顺序,运行父类调用子类的行为,并按照顺序进行处理哦。所为的生命周期就是先调用init方法,然后容器在去调用service方法哦!

    /** * Called by the servlet container to indicate to a servlet that the * servlet is being placed into service. See {@link Servlet#init}. * * <p>This implementation stores the {@link ServletConfig} * object it receives from the servlet container for later use. * When overriding this form of the method, call * <code>super.init(config)</code>. */ public void init(ServletConfig config) throws ServletException { this.config = config; this.init(); } /** * A convenience method which can be overridden so that there's no need * to call <code>super.init(config)</code>. * * <p>Instead of overriding {@link #init(ServletConfig)}, simply override * this method and it will be called by * <code>GenericServlet.init(ServletConfig config)</code>. * The <code>ServletConfig</code> object can still be retrieved via {@link * #getServletConfig}. */ public void init() throws ServletException { } /** * Called by the servlet container to allow the servlet to respond to * a request. See {@link Servlet#service}. * * <p>This method is declared abstract so subclasses, such as * <code>HttpServlet</code>, must override it. * * @param req the <code>ServletRequest</code> object * that contains the client's request * * @param res the <code>ServletResponse</code> object * that will contain the servlet's response * */ public abstract void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;

    续说HttpServlet

    HttpServlet也是个抽象类,不能直接进行实例化,必须给出子类才能实例化(即不能直接使用,只能继承它)。HttpServlet是采用Http协议进行通信的,所以它也实现Http协议中的多种方法,每种方法可以处理相应类型的请求HttpServlet的service()方法比较特殊,带public关键字的service()方法明显是继承自父类,它只接收HTTP请求,这里把相应的request和response转换为了基于HTTP协议的相应对象,最终将请求转到带protected关键字的service()方法中。protected service()方法根据请求的类型将请求转发到相应的doDelete()、doGet()、doOptions()、doPost()doPut()等方法中。所以开发自己的Servlet时,不需要覆盖HttpServlet的service()方法,因为该方法最终将请求转发相相应的doXXX方法中,只需要覆盖相应的doXXX方法进行请求处理即可。如果重写了该方法,那么就不会根据方法名调用其他具体的方法了。

    blade中处理分发route也是需要继承当前的HttpServlet进行处理哦,根据Path找到相应的处理类

    AbsDispatcherServlet

    其实就是相当于每次请求的时候都会调用这个Servlet,然后进行分派处理,无论是spring mvc 还是其他的mvc框架原理都是一样的。这个只是个抽象的类,这里处理了初始化了分发的DispatcherHandler 和单例Blade的引用,这里覆盖了父类GenericServlet的init方法,主要是DispatcherHandler中想要这个ServletContext这个数据哦,还有传入我们的routers这个路由总管家进行处理哦!

    /** * Blade Abstract DispatcherServlet */ public abstract class AbsDispatcherServlet extends HttpServlet { protected Blade blade; protected DispatcherHandler dispatcherHandler; @Override public void init(ServletConfig config) throws ServletException { blade = Blade.$(); this.dispatcherHandler = new DispatcherHandler(config.getServletContext(), blade.routers()); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.service(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.service(req, resp); } @Override public void destroy() { super.destroy(); } }

    DispatcherServlet 这里是真正的类哦,在Jeety中已经被容器设置可以调用的哦.

    EmbedJettyServer 在这个类中实现的哦。所以每次调用的时候都会经过这个的处理哦!

    import org.eclipse.jetty.webapp.WebAppContext; import com.blade.mvc.dispatch.DispatcherServlet; this.webAppContext = new WebAppContext(); Class< ? extends Servlet> servlet = isAsync ? AsyncDispatcherServlet.class : DispatcherServlet.class; ServletHolder servletHolder = new ServletHolder(servlet); servletHolder.setAsyncSupported(isAsync); servletHolder.setInitOrder(1); webAppContext.addServlet(servletHolder, "/");

    这里覆盖了HttpServlet的保护的方法就是处理,哈哈!每次来请求了都进行处理

    /** * Blade Core DispatcherServlet */ public class DispatcherServlet extends AbsDispatcherServlet { @Override protected void service(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws ServletException, IOException { httpRequest.setCharacterEncoding(blade.encoding()); httpResponse.setCharacterEncoding(blade.encoding()); httpResponse.setHeader("X-Powered-By", "Blade(" + Const.VERSION + ")"); httpRequest.setAttribute("org.apache.catalina.ASYNC_SUPPORTED", true); dispatcherHandler.handle(httpRequest, httpResponse); } }

    DispatcherHandler

    这里才是处理分发的重点的逻辑哦,当前类中有ServletContext and Routers。所有真正的mvc分发的逻辑。下次再聊~~

    https://github.com/otale/tale 主要是看到这个博客系统,才想去了解一下这个简单的web框架的!

    转载请注明原文地址: https://ju.6miu.com/read-34121.html

    最新回复(0)