Servlet/JSP背后的故事

Servlet、JSP对所有JAVA-WEB编程人员来说再熟悉不过了;但大家在使用的时候是否知道他们的关系呢?

 

1       Http协议

略(详见[LXH]Http协议.pdf

 

2       浏览器与服务器连接的过程

AServer端:启动并监听某个端口号(如8080

BClient端:通过浏览器发起对服务端的请求

CS:接收请求,并分配一个线程与之连接并开始相互通讯(HTTP,基于TCP

D、通讯完毕,双方断开连接,回收资源。

(类似Socket的通讯过程,详见[LXH]Java网络编程.pdf

3       SERVLET/JSP

Server端,都是通过java类取数据并返回html格式的字符串给浏览器解析

3.1最早的方式:Servlet

html标签字符串写在servlet类里,最后response给浏览器

                   doGet(…){

                                      Out.println(“<html><head></head><body>”);

                                      ….

                                      Out.println(“</body></html>”)

                                      …

}

这样的写法很麻烦,而且每次都要在.java类里修改,重新编译,再发布,不便于修改。

3.1.1                           HttpServlet源码分析

Provides an abstract class to be subclassed to create an HTTP servlet suitable for a Web site. A subclass of HttpServlet must override at least one method, usually one of these: 必须重写至少1个以下方法

  • doGet, if the servlet supports HTTP GET requests
  • doPost, for HTTP POST requests
  • doPut, for HTTP PUT requests
  • doDelete, for HTTP DELETE requests
  • init and destroy, to manage resources that are held for the life of the servlet
  • getServletInfo, which the servlet uses to provide information about itself

service()接收标准HTTP请求,并将其转发给其所要执行的方法(如doGetdoPost),即先执行service()后自动执行其他方法

查看一下HttpServlet.java源码片段(tomcat源码里可以下载到)

protectedvoid service(HttpServletRequest req, HttpServletResponse resp)

        throws ServletException, IOException {

        String method = req.getMethod();

              //往下可以看出,最后还要负责转发原请求

        if (method.equals(METHOD_GET)) {

                     ...

                     doGet(req,resp);

}elseif (method.equals(METHOD_HEAD)) {

            ...

            doHead(req, resp);

        } elseif (method.equals(METHOD_POST)) {

            doPost(req, resp);           

        } elseif (method.equals(METHOD_PUT)) {

            doPut(req, resp);                   

        } elseif (method.equals(METHOD_DELETE)) {

            doDelete(req, resp);           

        } elseif (method.equals(METHOD_OPTIONS)) {

            doOptions(req,resp);           

        } elseif (method.equals(METHOD_TRACE)) {

            doTrace(req,resp);           

        } else {

                ...

resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);

}

}

因此重写service()方法后如果不再调用super.service(req,resp);则不会再做原有的动作了。

 

doGet()方法(默认返回错误,需子类自己重写)

protectedvoid doGet(HttpServletRequest req, HttpServletResponse resp)

        throws ServletException, IOException

    {

        String protocol = req.getProtocol();

        String msg = lStrings.getString("http.method_get_not_supported");

        if (protocol.endsWith("1.1")) {

            resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);

        } else {

            resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);

        }

}

 

doPost()方法(默认返回错误,需子类自己重写)

protectedvoid doPost(HttpServletRequest req, HttpServletResponse resp)

        throws ServletException, IOException {

 

        String protocol = req.getProtocol();

        String msg = lStrings.getString("http.method_post_not_supported");

        if (protocol.endsWith("1.1")) {

            resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);

        } else {

            resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);

        }

    }

3.2Jsp的方式(底层也是基于Servlet的方式)

JSP ParserJSP解析器

              负责将*.jsp文件转换成一个Servlet类,并且编译供Servlet分析器来执行---最后又走到Servlet流程

Jasper.jarjsp-api.jarservlet-api.jar等包(一般java web server都会包含)

我们可以在jsp里把java代码嵌进去

<html><head></head><body>

<% 执行java代码%>

</body></html>

tp

 

 

               (JSP执行过程1)

从上图可以看出,*.jsp通过jsp parser会自动生成一个*.java类,并且编译成*.class文件,供Servlet使用,最后也是走servlet的流程---这个工作一般由web server来完成

 

Tomcat为例

Work文件夹里面会为jsp生成相关的java类,并完成编译供运行调用

              index.jsp------àindex_jsp.java--àindex_jsp.class

              查看如下代码段:

              public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase

implements org.apache.jasper.runtime.JspSourceDependent {

….

                      out.write("<html>\r\n");

    out.write("<head>\r\n");

    out.write("\t<title>\r\n");

        ….

}

          查看HttpJspBase源码

org.apache.jasper.runtime
Class HttpJspBase

        java.lang.Object
         javax.servlet.GenericServlet
                javax.servlet.http.HttpServlet
                        org.apache.jasper.runtime.HttpJspBase
 
   其就是继承HttpServlet,所以说jsp其最终还是走servlet流程

 

 

 

Web Server 执行生成和编译的时机

--------并不是每次调用都执行,而是在文件创建或修改后的第一次调用,才会执行生成和编译操作.

 

 

推荐阅读

 

代码之余轻松一下:当前热门-人民的名义

 

JAVAEE容器如何管理EntityManager和PersistenceContext

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值