传送门 ☞ 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类,用于处理客户端提交的用户登录请求。

  1. package cn.lynn.servlet;
  2.  
  3. import cn.lynn.tomjetty.HttpServletImpl;
  4. import cn.lynn.tomjetty.Request;
  5. import cn.lynn.tomjetty.Response;
  6.  
  7. public class LoginServlet extends HttpServletImpl {
  8.  
  9. @Override
  10. public void doGet(Request req, Response res) {
  11. String username = req.getParameterValue("username"); // 接收客户端请求参数
  12. String password = req.getParameterValue("password");
  13. if (username.equals("lynnliget") && password.equals("123456")) { // 执行简单逻辑判断
  14. res.out.print("Hello, " + username + "<br>"); // 输出结果信息
  15. }
  16. res.out.close();
  17. }
  18.  
  19. @Override
  20. public void doPost(Request req, Response res) {
  21. String username = req.getParameterValue("username");
  22. String password = req.getParameterValue("password");
  23. if (username.equals("lynnlipost") && password.equals("123456")) {
  24. res.out.print("Hello, " + username + "<br>");
  25. }
  26. res.out.close();
  27. }
  28.  
  29. }

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

  1. /login=cn.lynn.servlet.LoginServlet

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

  1. package cn.lynn.tomjetty;
  2.  
  3. import java.io.FileInputStream;
  4. import java.io.IOException;
  5. import java.util.Properties;
  6.  
  7. public class WebUtil {
  8.  
  9. private static Properties props = new Properties();
  10.  
  11. static {
  12. try {
  13. props.load(new FileInputStream(".//webapps//web.config"));
  14. } catch (IOException e) {
  15. e.printStackTrace();
  16. System.exit(0);
  17. }
  18. }
  19.  
  20. public static String getValue(String key) {
  21. return props.getProperty(key);
  22. }
  23. }

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

  1. package cn.lynn.tomjetty;
  2.  
  3. import java.io.PrintWriter;
  4.  
  5. public class Response {
  6. public PrintWriter out;
  7.  
  8. public PrintWriter getOut() {
  9. return out;
  10. }
  11.  
  12. public void setOut(PrintWriter out) {
  13. this.out = out;
  14. }
  15.  
  16. }

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

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

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

1.GET方式提交

2.POST方式提交

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

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

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

  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  2. "http://www.w3.org/TR/html4/loose.dtd">
  3. <html>
  4. <head>
  5. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  6. <title>404</title>
  7. <link href="css/css0.css" rel="stylesheet" type="text/css">
  8. </head>
  9.  
  10. <body>
  11. <table width="50%" border="0" align="center" cellpadding="10" cellspacing="0">
  12. <tr>
  13. <td bgcolor="#A4A4A4"><table width="100%" border="0" cellpadding="0" cellspacing="0">
  14. <tr>
  15. <td bgcolor="#FFFFFF"><table width="100%" border="0" cellpadding="15" cellspacing="1">
  16. <tr>
  17. <td bgcolor="#E1E1E1"><div align="center"><strong>404</strong> Request Page Not Found!</div></td>
  18. </tr>
  19. </table></td>
  20. </tr>
  21. </table></td>
  22. </tr>
  23. </table>
  24. </body>
  25. </html>

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

  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  2. "http://www.w3.org/TR/html4/loose.dtd">
  3. <html>
  4. <head>
  5. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  6. <title>500</title>
  7. <style type="text/css">
  8. <!--
  9. .style1 {
  10. color: #FF0000;
  11. font-weight: bold;
  12. }
  13. -->
  14. </style>
  15. </head>
  16.  
  17. <body>
  18. <table width="50%" border="0" align="center" cellpadding="10" cellspacing="0">
  19. <tr>
  20. <td bgcolor="#A4A4A4"><table width="100%" border="0" cellpadding="0" cellspacing="0">
  21. <tr>
  22. <td bgcolor="#FFFFFF"><table width="100%" border="0" cellpadding="15" cellspacing="1">
  23. <tr>
  24. <td bgcolor="#E1E1E1"><div align="center"><strong>500</strong> <span class="style1">System Error.Please Wait...</span> </div></td>
  25. </tr>
  26. </table></td>
  27. </tr>
  28. </table></td>
  29. </tr>
  30. </table>
  31. </body>
  32. </html>

四、TomJetty处理请求流程:

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

2.解析出请求的url;

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

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

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

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

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

  1. // 封装响应
  2. Response res = new Response();
  3.  
  4. // 有请求处理类就加载,无则找文件
  5. if(WebUtil.getValue(header.getUrl()) != null) {
  6. try {
  7. IServlet servlet = (IServlet) Class.forName(WebUtil.getValue(header.getUrl())).newInstance();
  8. res.setOut(new PrintWriter(out));
  9. servlet.service(req, res);
  10. } catch(Exception e) {// 编译Servlet发生异常,加载500
  11. File file = new File(TomJettyUtil.getValue("tomjetty.webapps"), "500.htm");
  12. fin = new FileInputStream(file);
  13. byte[] buf = new byte[(int) file.length()];
  14. fin.read(buf);
  15. out.write(buf);
  16. }
  17. } else {
  18. File file = new File(TomJettyUtil.getValue("tomjetty.webapps"),header.getUrl()); // 从配置文件检索服务端静态页面存放目录,定位到服务器端的静态页面
  19. if(!file.exists()) {// 请求静态页面不存在,加载404
  20. file = new File(TomJettyUtil.getValue("tomjetty.webapps"), "404.htm");
  21. }
  22. fin = new FileInputStream(file);
  23. byte[] buf = new byte[(int) file.length()];
  24. fin.read(buf); // 读取静态页面内容
  25. out.write(buf); // 将静态页面内容写回给客户端浏览器显示
  26. }

[置顶] 自己动手写Web容器之TomJetty之六:动态页面引入的更多相关文章

  1. [置顶] 【J2SE 】1136 容器之旅

    开篇引言 本篇文章我将要详细的介绍一下什么是容器?以及什么是1136?来系统全面的了解容器,以及容器的应用,下面就进入我们的容器之旅吧! 1.什么是容器? 用来存储和组织其他对象的对象.我们也可以这样 ...

  2. 自己动手写web框架----1

    本文可作为<<自己动手写struts–构建基于MVC的Web开发框架>>一书的读书笔记. 一个符合Model 2规范的web框架的架构图应该如下: Controller层的Se ...

  3. [置顶] 浅谈大型web系统架构

    转载原文:http://blog.csdn.net/dinglang_2009/article/details/6863697 分类: 大规模Web 2.0架构 2011-10-11 18:27 12 ...

  4. [置顶] 提高生产力:Web开发基础平台WebCommon的设计和实现

    Web开发中,存在着各种各样的重复性的工作.为了提高开发效率,不在当码农,我在思考和实践如何搭建一个Web开发的基础平台. Web开发基础平台的目标和功能 1.提供一套基础的开发环境,整合了常用的框架 ...

  5. [置顶] Xamarin android 调用Web Api(ListView使用远程数据)

    xamarin android如何调用sqlserver 数据库呢(或者其他的),很多新手都会有这个疑问.xamarin android调用远程数据主要有两种方式: 在Android中保存数据或调用数 ...

  6. 自己动手写web框架----2

    在上一节,我们自己写的web框架,只能运行显示一个HelloWorld.现在我们对其进行一次加工,让他至少能运行一个登陆程序. 首先看login.jsp <%@ page contentType ...

  7. [置顶] 使用Android OpenGL ES 2.0绘图之六:响应触摸事件

    传送门 ☞ 系统架构设计 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229 传送门 ☞ GoF23种设计模式 ☞ 转载请注明 ☞ http://blog.csd ...

  8. [Web 前端] 006 css 三种页面引入的方法

    1. 外链式 用法 step 1: 在 html 文档的 head 头部分写入下方这句话 <link rel="stylesheet" href="./xxx.cs ...

  9. 自己动手写一个简单的(IIS)小型服务器

    因为第一次在博客园发表随笔,不太会用,这个笔记是我之前在印象笔记中写好的,然后直接copy过来,有兴趣自己做一个IIS服务器的小伙伴们可以参照下面的流程做一次,也可以叫我要源代码,不过要做完,我觉得花 ...

随机推荐

  1. 侧滑UI

    1.视图 activity_main.xml <com.zyhui.cehua.SlidingMenu xmlns:android="http://schemas.android.co ...

  2. Arduino 入门程序示例之一片 LED(2015-06-11)

    概述 从点到线,从线到面.现在开始要来一片的 LED 了,一大波的 LED 正在到来! 示例程序 因为手头没有现成的模块,手头只有 595,所以这里每一个示例程序都是使用 74HC595 扩展 IO ...

  3. Mars的mp3实例

    Mars的mp3实例第一课: 关于menu: package mars.mp3player01; import mars.down.HttpDownloader; import android.app ...

  4. Python 第七篇:socket编程

    一:socket基础: 1.1:Socket基础: socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,对于文件用[打开][读写][关闭]模式来操作.socket就是该模 ...

  5. 【Java Web】使用URLRewrite实现网站伪静态

    大部分搜索引擎都会优先考虑收录静态的HTML页面,而不是动态的*.jsp.*.php页面.但实际上绝大部分网站都是动态的,不可能全部是静态的HTML页面,因此互联网上大部分网站都会考虑伪静态——就是将 ...

  6. JVM调优总结(九)-新一代的垃圾回收算法

    垃圾回收的瓶颈 传统分代垃圾回收方式,已经在一定程度上把垃圾回收给应用带来的负担降到了最小,把应用的吞吐量推到了一个极限.但是他无法解决的一个问题,就是Full GC所带来的应用暂停.在一些对实时性要 ...

  7. Android之——Fragment生命周期(日志截图版)

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/46867159

  8. Oracle数据库索引使用及索引失效总结

    容易引起oracle索引失效的原因很多: 1.在索引列上使用函数.如SUBSTR,DECODE,INSTR等,对索引列进行运算.需要建立函数索引就可以解决了. 2.新建的表还没来得及生成统计信息,分析 ...

  9. mac下和windows下清空DNS缓存

    在WIN下: > ipconfig /flushdns 在mac下: 对于低版本系统,在命令行窗口(terminal)输入 lookupd -flushcache 即可: $ sudo look ...

  10. 基于visual Studio2013解决C语言竞赛题之1043求末尾0个数

       题目 解决代码及点评 /* 43. 求n!的末尾有多少个零.可以通过检查n!含有多少个10的因数来求它末尾零的个数. 因为10=2×5,在n!中含有2的因数显然多于含有5的因数. 一 ...