传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229

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

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

1动态页面请求处理

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

1.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();
    }

}

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

/login=cn.lynn.servlet.LoginServlet

1.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);
    }
}

1.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;
    }

}

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

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

2处理动态请求效果展示

2.1GET方式提交


2.2POST方式提交




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

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

3.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>

3.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>

4TomJetty处理请求流程

(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); // 将静态页面内容写回给客户端浏览器显示
}

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐