zoukankan      html  css  js  c++  java
  • 深入刨析tomcat 之---第1篇,解决第1,2章bug 页面不显示内容Hello. Roses are red.

    writedby 张艳涛,

    第一个问题是不显示index.html网页

    19年才开始学java的第二个月,就开始第一遍看这本书,我估计当初,做第一章的一个案例,自己写代码,和验证就得一天吧,当初就发现了这个问题,chrome浏览器不显示localhost:8080/index.html页面,还特意在培训班的课堂上问了下,老师说是web服务器没有写http头,这个老师一眼就看出来了,还行;但通过ie浏览器就没这个问题,真是服气了~~~

    先贴下解决这个问题的代码

    package com.zyt.tomcat.ex01;
    
    import java.io.*;
    
    public class Response {
        private static final int  BUFFER_SIZE=1024;
        Request request;
        OutputStream output;
    
        public Response(OutputStream output) {
            this.output = output;
        }
    
        public void setRequest(Request request) {
            this.request = request;
        }
        public void sendStaticResource() throws IOException{
            byte[] bytes = new byte[BUFFER_SIZE];
            FileInputStream fis=null;
            File file = new File(HttpServer.WEB_ROOT, request.getUri());
            PrintWriter out=null;
            try {
                if (file.exists()) {
                    out = new PrintWriter(output);
                    fis = new FileInputStream(file);
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    int ch = fis.read(bytes, 0, BUFFER_SIZE);
                    while (ch != -1) {
                        baos.write(bytes,0,ch);
                        ch = fis.read(bytes, 0, BUFFER_SIZE);
                    }
                    byte[] array = baos.toByteArray();
                    out.println("HTTP/1.1 200 OK");
                    out.println("Server: Molly");
                    out.println("Content-Type: text/html; charset=UTF-8");
                    out.println("Content-Length: "+array.length);
                    out.println("");
                    out.flush();
                    output.write(array,0,array.length);
    
    
                }else {
                    // file not found
                    String errorMessage = "HTTP/1.1 404 File Not Found
    " +
                            "Content-Type: text/html
    " +
                            "Content-Length: 23
    " +
                            "
    " +
                            "<h1>File Not Found</h1>";
                    output.write(errorMessage.getBytes());
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (fis != null) {
                    fis.close();
                }
            }
        }
    }

    你别看这小段内容,其中有一个问题就是,你要写Content-Length的值,如果你先写http头,在读头文件,那你就没法知道文件的大小的值了,这里采取了一个第三变量array来保存文件的内容,这样子就可以先写http头内容,完成之后,接着写文件内容;

    这全网独一份,不过我也是在java并发编程的艺术这边书上参考了4.4章,

    再顺便提另外一个问题,这个index.html的代码如下

    <html>
    <head>
    <title>Welcome to BrainySoftware</title>
    </head>
    <body>
    <img src="./images/logo.gif">
    <br>
    Welcome to BrainySoftware.
    </body>
    </html>

    这个图片加载的标签img src="",这个是加载静资源,要说的是静态资源是通过浏览器先接受index.html文件的内容,解析之后再进行了一次http请求得到了jpg图片

    并不是一次返回全部内容,看证据,

    浏览器端

    服务器端

    第二个问题是: 浏览器输入 http://localhost:8080/servlet/PrimitiveServlet ,不显示内容

    问题描述,这个问题是,第二章的第一案例,加载servlet类,实现动态加载,这个问题,大概在2020年的4月份自己想解决,想了好几天都没想到方法.

    这个问题也是一样,他的PrimitiveServlet代码主要是如下,他也没有写http头

    import javax.servlet.*;
    import java.io.IOException;
    import java.io.PrintWriter;
    
    public class PrimitiveServlet implements Servlet {
    
      public void init(ServletConfig config) throws ServletException {
        System.out.println("init");
      }
    
      public void service(ServletRequest request, ServletResponse response)
        throws ServletException, IOException {
        System.out.println("from service");
        PrintWriter out = response.getWriter();
        out.println("Hello. Roses are red.");
        out.print("Violets are blue.");
      }
    
      public void destroy() {
        System.out.println("destroy");
      }
    
      public String getServletInfo() {
        return null;
      }
      public ServletConfig getServletConfig() {
        return null;
      }
    
    }

    去年4月份想的方法是,在

                servlet = ((Servlet) myClass.newInstance());
                servlet.service(((ServletRequest) request), ((ServletResponse) response));

    service方法之前,给out写一个http 头文件,但是没有解决 out.println("Content-Length: " 是多少); 文件长度的值的问题;

    自己就一直想一直想,没想出来,今天下午,同意遇到这个问题了,现在可能对java 的知识理解深入了还是怎么开窍了,

    发现自己之前提的问题就是一个错误问题,我们在执行servlet.service()方法的时候,service的功能是什么???之前我理解的是servlet

    是给浏览器返回网页,这是错误的,在servlet中,你可以只是sout("hello")回头打印一句话,你不给浏览器回复,那么浏览器只是没得到回复,(网页空白)

    那么我的servlet功能实现了吗?实现了控制台已经打印了hello,那么如果你要给浏览器回复一个网页,那么你要在service()方法里面写http头文件和httpbody

    不应该servletProcessor1.java这个里,在反射调用servket,service 之前写http头文件

    更改后的文件为

    import javax.servlet.*;
    import java.io.IOException;
    import java.io.PrintWriter;
    
    public class PrimitiveServlet implements Servlet {
    
      public void init(ServletConfig config) throws ServletException {
        System.out.println("init");
      }
    
      public void service(ServletRequest request, ServletResponse response)
        throws ServletException, IOException {
        System.out.println("from service");
        PrintWriter out = response.getWriter();
        out.println("HTTP/1.1 200 OK");
        out.println("Server: Molly");
        out.println("Content-Type: text/html; charset=UTF-8");
    
        out.println("");
        out.flush();
        out.println("Hello. Roses are red.");
        out.print("Violets are blue.");
      }
    
      public void destroy() {
        System.out.println("destroy");
      }
    
      public String getServletInfo() {
        return null;
      }
      public ServletConfig getServletConfig() {
        return null;
      }
    
    }

    增加文件如标记所示,这个又遇到一个问题,你得javac编译他,但不能用idea 因为这个类没有包名

    所以你要使用javac 带依赖编译,如何编译呢?将源码包中的lib文件方法webroot文件夹下面,运行如下指令

    D:wksp_studydesignbookwebroot>javac  -encoding UTF-8 -classpath .;D:wksp_studydesignbookwebrootlib/servlet.jar PrimitiveServlet.java

    如果你直接java 类名,会报错,提示

    PrimitiveServlet.java:5: 错误: 找不到符号
    public class PrimitiveServlet implements Servlet {
    ^
    符号: 类 Servlet
    PrimitiveServlet.java:7: 错误: 找不到符号
    public void init(ServletConfig config) throws ServletException {
    ^
    符号: 类 ServletConfig
    位置: 类 PrimitiveServlet
    PrimitiveServlet.java:7: 错误: 找不到符号
    public void init(ServletConfig config) throws ServletException {
    ^
    符号: 类 ServletException
    位置: 类 PrimitiveServlet
    PrimitiveServlet.java:11: 错误: 找不到符号
    public void service(ServletRequest request, ServletResponse response)
    ^
    符号: 类 ServletRequest
    位置: 类 PrimitiveServlet
    PrimitiveServlet.java:11: 错误: 找不到符号
    public void service(ServletRequest request, ServletResponse response)

    =====================================================

    通过如上一番操作,你就能看到如下界面了

    结束语:

    1,之前打印一章的案例,得慢慢蹭蹭,现在熟练运用了idea的.var .if .nn .try .while 一点代码简直起飞呀,写代码行云流水,真是一种享受;

    2,知识是需要循序渐进的,相关知识的积累对当前表面的知识是有很大影响的,比如我问你个问题,jvm的gc是处理垃圾对象,那么垃圾对象是怎么产生的呢? 答案是:  A.func1 调用 B.func2 在调用C.func3 那么程序的栈帧中同时有三个方法栈,每个方法中都有自己的局部变量,每个局部变量对应一个jvm对象,如果你在func3中一直while 那么,这个时候jvm没有垃圾,事实是你func3调用玩了,你返回了,摧毁了func3的栈,局部变量给摧毁了,那么  局部变量 obj= new Obejct();  obj 没了, new Object()还在,那么这个new Object()就是jvm的垃圾,同样,你从func1中返回,那么fucn1,2,3中的局部变量都是垃圾了

    3.这是我第三次敲这个案例才醒悟了,没那么简单呢,即使是涛哥这么牛逼的人~~~

  • 相关阅读:
    linux下tomcat 重启和查看日志
    js 下载文件 不直接打开的方法
    linux 安装jdk1.7
    linux下安装nginx
    mysql5.6安装
    微信小程序js倒计时功能
    Ajax 页面跳转例子
    购买阿里云免费https证书,配置tomcat实现https加密访问
    Ajax 实现数组传递(Java)
    mysql 游标实例一
  • 原文地址:https://www.cnblogs.com/zytcomeon/p/14950708.html
Copyright © 2011-2022 走看看