zoukankan      html  css  js  c++  java
  • [置顶] 自己动手写Web容器之TomJetty之六:动态页面引入

    传送门 ☞ Android兵器谱 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229

    传送门 ☞ 1.Web服务内功经脉

    传送门 ☞ 2.让服务动起来

    传送门 ☞ 3.掀起请求盖头来

    传送门 ☞ 4.静态页面起步

    传送门 ☞ 5.包装请求参数

            在上一节,我们已经完成了TomJetty服务器处理静态页面请求的功能。但是只能处理静态页面请求的服务器并不能满足我们的要求,所以本节我们将为TomJetty服务器完成动态页面请求的处理工作。

            所谓动态页面请求,无非就是客户端发送一个请求的url地址或者将一些请求参数提交给某一个url地址,服务器端首先接收到这个url地址并检索其在服务端程序中对应的某个处理类(Servlet),然后在该处理类中执行业务逻辑后产生结果,最终转发给相应的页面在客户端浏览器中显示结果。

    一、动态页面请求处理

            对于Java而言,Web容器中用来处理动态页面请求的服务类实质上就是Servlet。接下来我们就实现一个LoginServlet来处理客户端提交的用户登录信息。

    1.新建一个LoginServlet类,用于处理客户端提交的用户登录请求。

    package cn.lynn.servlet;
    
    import cn.lynn.tomjetty.HttpServletImpl;
    import cn.lynn.tomjetty.Request;
    import cn.lynn.tomjetty.Response;
    
    public class LoginServlet extends HttpServletImpl {
    
        @Override
        public void doGet(Request req, Response res) {
            String username = req.getParameterValue("username"); // 接收客户端请求参数
            String password = req.getParameterValue("password");
            if (username.equals("lynnliget") && password.equals("123456")) { // 执行简单逻辑判断
                res.out.print("Hello, " + username + "<br>"); // 输出结果信息
            }
            res.out.close();
        }
        
        @Override
        public void doPost(Request req, Response res) {
            String username = req.getParameterValue("username");
            String password = req.getParameterValue("password");
            if (username.equals("lynnlipost") && password.equals("123456")) {
                res.out.print("Hello, " + username + "<br>");
            }
            res.out.close();
        }
    
    }

    2.在webapps目录下新建web.config文件,用于配置动态页面请求路径与请求处理类的对应关系。

    /login=cn.lynn.servlet.LoginServlet

    3.新建WebUtil类,用来从web.config文件中读取请求处理类的名称并生成该类的实例。该类的设计和用法与TomJettyUtil类基本一致。

    package cn.lynn.tomjetty;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.util.Properties;
    
    public class WebUtil {
    
        private static Properties props = new Properties();
        
        static {
            try {
                props.load(new FileInputStream(".//webapps//web.config"));
            } catch (IOException e) {
                e.printStackTrace();
                System.exit(0);
            }
        }
        
        public static String getValue(String key) {
            return props.getProperty(key);
        }
    }
    

    4.新建一个Response类,用于封装服务器对请求的响应。目前我只存放打印流PrintWriter。

    package cn.lynn.tomjetty;
    
    import java.io.PrintWriter;
    
    public class Response {
        public PrintWriter out;
    
        public PrintWriter getOut() {
            return out;
        }
    
        public void setOut(PrintWriter out) {
            this.out = out;
        }
    
    }
    

    5.在TomJetty类的run()方法中,我们新增如下代码片段,用来处理动态页面请求。

    IServlet servlet = (IServlet) Class.forName(WebUtil.getValue(header.getUrl())).newInstance();
                        res.setOut(new PrintWriter(out));
                        servlet.service(req, res);

    二、处理动态请求效果展示

    1.GET方式提交


    2.POST方式提交




            这里我们默认请求都携带参数信息。至于其他输入请求的格式可能导致页面出现的不友好信息的情景,请读者自行处理^_^。

    三、添加错误提示页面,以增加服务友好度。

    1.添加404.htm至webapps目录下,用于提示用户请求页面不存在。

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>404</title>
    <link href="css/css0.css" rel="stylesheet" type="text/css">
    </head>
    
    <body>
    <table width="50%"  border="0" align="center" cellpadding="10" cellspacing="0">
      <tr>
        <td bgcolor="#A4A4A4"><table width="100%"  border="0" cellpadding="0" cellspacing="0">
          <tr>
            <td bgcolor="#FFFFFF"><table width="100%"  border="0" cellpadding="15" cellspacing="1">
              <tr>
                <td bgcolor="#E1E1E1"><div align="center"><strong>404</strong> Request Page Not Found!</div></td>
              </tr>
            </table></td>
          </tr>
        </table></td>
      </tr>
    </table>
    </body>
    </html>
    

    2.添加500.htm至webapps目录下,以提示服务器编译问题。

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>500</title>
    <style type="text/css">
    <!--
    .style1 {
    	color: #FF0000;
    	font-weight: bold;
    }
    -->
    </style>
    </head>
    
    <body>
    <table width="50%"  border="0" align="center" cellpadding="10" cellspacing="0">
      <tr>
        <td bgcolor="#A4A4A4"><table width="100%"  border="0" cellpadding="0" cellspacing="0">
          <tr>
            <td bgcolor="#FFFFFF"><table width="100%"  border="0" cellpadding="15" cellspacing="1">
              <tr>
                <td bgcolor="#E1E1E1"><div align="center"><strong>500</strong> <span class="style1">System Error.Please Wait...</span> </div></td>
              </tr>
            </table></td>
          </tr>
        </table></td>
      </tr>
    </table>
    </body>
    </html>
    

    四、TomJetty处理请求流程:

    1.接收客户端发送的请求;

    2.解析出请求的url;

    3.在web.config文件中检索是否存在该url对应的Servlet类。

    4.如果存在该Servlet,就是动态请求,交给该Servlet去处理它。

    5.如果不存在,就视为静态请求,加载tomjetty.config文件中的配置信息去处理它。

    6.在上述处理过程中,如果遇到服务器端处理类生成或代码问题,就加载500.htm页面;如果是请求页面找不到,则加载404.htm页面。

            那么根据上述服务器处理请求的完整流程,TomJetty类的run()方法中处理请求的代码片段就应该是下面这样:

    // 封装响应
    Response res = new Response();
                
    // 有请求处理类就加载,无则找文件
    if(WebUtil.getValue(header.getUrl()) != null) {
        try {
            IServlet servlet = (IServlet) Class.forName(WebUtil.getValue(header.getUrl())).newInstance();
            res.setOut(new PrintWriter(out));
            servlet.service(req, res);
        } catch(Exception e) {// 编译Servlet发生异常,加载500
            File file = new File(TomJettyUtil.getValue("tomjetty.webapps"), "500.htm");
            fin = new FileInputStream(file);
            byte[] buf = new byte[(int) file.length()];
            fin.read(buf);
            out.write(buf);
        }
    } else {
        File file = new File(TomJettyUtil.getValue("tomjetty.webapps"),header.getUrl()); // 从配置文件检索服务端静态页面存放目录,定位到服务器端的静态页面
        if(!file.exists()) {// 请求静态页面不存在,加载404
            file = new File(TomJettyUtil.getValue("tomjetty.webapps"), "404.htm");
        } 
        fin = new FileInputStream(file);
        byte[] buf = new byte[(int) file.length()];
        fin.read(buf); // 读取静态页面内容
        out.write(buf); // 将静态页面内容写回给客户端浏览器显示
    }
  • 相关阅读:
    《转》python学习(5)--数据类型
    《转》python学习(4)对象
    《转》python学习(3)
    《转》python学习--基础下
    《转》python学习--基础上
    python初学总结(二)
    并发编程学习笔记(9)----AQS的共享模式源码分析及CountDownLatch使用及原理
    并发编程学习笔记(8)----ThreadLocal的使用及源码分析
    并发编程学习笔记(7)----线程之间的通信
    并发编程学习笔记(6)----公平锁和ReentrantReadWriteLock使用及原理
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3148127.html
Copyright © 2011-2022 走看看