您的位置:首页 > 理论基础 > 计算机网络

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

2017-03-12 15:26 405 查看

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框架的!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐