Java基础5JavaWeb之简单追踪javax.servlet类库

Posted 南瓜__pumpkin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java基础5JavaWeb之简单追踪javax.servlet类库相关的知识,希望对你有一定的参考价值。


查看javax.servlet库

  环境说明:安装IDEA并在Tomcat中创建JavaWeb项目后,会出现文件 index.jspHelloServlet.java ,其中 HelloServlet.java 文件引用了 javax.servlet 库的相关内容,因此对该类库进行一番探查。

  找到javax.servlet库:通过IDEA的Project视图,在外部库Exernal Libraries中可以找到该库。

  查看javax.servlet-api-4.0.1.jar库,看到有3个二级类库,以及很多Class文件。

  在Tomcat的HelloWorld中,HelloServlet.java文件引用库文件、继承父类的代码如下。我们接下来分析javax.servlet/http/HttpServlet.class文件。值得一提的是,.class文件是.java源文件编译后的文件。

import java.io.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;


@WebServlet(name = "helloServlet", value = "/hello-servlet")
public class HelloServlet extends HttpServlet {

HttpServlet.class文件

介绍

  代码量: 查看HttpServlet.class,编译后的代码量有200余行,具有一定可读性。IDEA提供了反编译的功能,反编译后文件具有918行代码量。(相当一部分是代码注释)

  Demo调用的类: 在Tomcat定义的HelloServlet.java文件中,自定义类继承了 HttpServlet类 , 调用了 doGet()方法

  抽象类 HttpServlet: 值得一提的是,HttpServlet是Servlet接口的一个实现类,并且它是一个抽象类,servlet.http包中定义了采用HTTP通信协议(一个无状态协议)的HttpServlet类。(抽象类不能实例化,只能被继承)


分析HelloServlet.java跟踪代码

跟踪 PrintWriter out = response.getWriter();

  查看反编译后的HttpServlet.java文件,在167行找到 doGet()方法 的代码如下。(简单了解)

参数:请求对象、响应对象。
异常声明:可能存在Servlet程序异常、IO异常。
变量:protocol、msg
相关方法:请求对象的协议信息……
protected void 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);
        }
    }

  追查doGet()方法: 该方法在HelloServlet.java文件中被重写,所以查看HelloServlet.java的相关代码,如下。重写的doGet()方法,主要调用了 HttpServletResponse对象 的 setContentType() 和 getWriter()方法。

public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("text/html");

        // Hello
        PrintWriter out = response.getWriter();
        out.println("<html><body>");
        out.println("<h1>" + message + "</h1>");
        out.println("</body></html>");
    }

  追查HttpServletResponse对象: 打开HttpServletResponse.java文件,首先查看对象声明,发现是一个接口,查看该文件的代码,发现主要用于设置响应信息。

  • public interface HttpServletResponse extends ServletResponse

  追查ServletResponse对象: 打开文件,查看对象声明,发现还是一个接口。(一个类通过继承接口的方式,从而来继承接口的抽象方法)

  该文件把 getWriter() 定义为 PrintWriter类,目前已经找到最终的文件。HelloServlet文件中,定义 out 为 PrintWriter类的实例对象,用于处理相关数据。

  • public interface ServletResponse // 接口
  • public PrintWriter getWriter() throws IOException; // 方法

跟踪 response.setContentType(“text/html”);

  通过代码跟踪发现如下调用链,通过跟踪分析我们可以推断,response.setContentType 用于自定义设置响应的内容类型,然后设置内容会被输出流返回给客户端。

  • Demo文件:HelloServlet.java,引用了HttpServletResponse对象;
  • 子接口文件:HttpServletResponse.class,没有.setContenType方法
  • 父接口文件:ServletResponse,找到源码:public void setContentType(String type);

新问题

PrintWriter类有哪些使用方法?

HttpServletResponse.setContentType(“text/html”)只设置了响应的内容类型,谁负责取出HttpServletResponse对象的数据?

以上是关于Java基础5JavaWeb之简单追踪javax.servlet类库的主要内容,如果未能解决你的问题,请参考以下文章

Java Web之Servlet技术

Java项目构建基础之统一日志收集

基础入门_Python-模块和包.深入Celery之节点管理/任务调度/任务追踪?

基础篇丨链路追踪(Tracing)其实很简单

Java 图形用户界面之javax.swing包 ContainerJComponentJApplet

大数据Java基础第二十天作业