基于Java实现的Web服务器与测试工具开发

资源下载地址:https://download.csdn.net/download/sheziqiong/85706486
资源下载地址:https://download.csdn.net/download/sheziqiong/85706486

Web 服务器与测试工具开发

一、系统概述

1.1 系统背景

基于 Java 编程语言,利用 http socket 通信技术,写一个小型的 Web 服务器与一个爬虫的测试工具,来对比分析所写的服务器获取到的页面源码与从 Tomcat 获取的相似度。

1.2 系统目标

序号目标内容
1客户端可以通过 GET 和 POST 获取信息
2支持 HTML、servlet、JSP 页面的访问
3支持标准的 filter 行为
4服务器与一个客户端能维持一个会话
5客户端支持带参数的 POST 获取
6客户端能够比较获取到的网页结果

1.3 开发环境与工具

序号类别具体需求备注
1硬件Windows 10
2软件eclipse

二、需求分析

2.1 系统需求概述

小型 Web 服务器:

支持客户端的网页请求,进行并发处理,缩短请求的响应时间。

可响应 GET、POST(HTML、servlet、JSP)页面的请求。

对每次网页请求都进行过滤(filter)。

支持 request、response 的跳转请求。

可维持一个客户端与服务器间的会话(session)。

客户端模拟器:

通过输入端口连接 Web 服务器,完成交互。

支持 get 方法的页面请求。

支持 post 方法,可以对参数进行封装。

构建测试用例:

手工将“Java Web 服务器开发”中的示例部署到 Tomcat 中,执行程序,抓取各个页面的输出,保存成“标准结果”,每个页面一个结果文件。

手工将“Java Web 服务器开发”中的示例部署到自己开发的 Web 服务器中。采用本程序模拟上述访问过程,将“模拟结果”进行保存。

通过“实习 3 中”的文件相似性的方法对于“模拟结果”和“标准结果进行比较”,显示输出的结果。

2.2 功能性需求

可以使用 GET 方法请求网页并得到正确的返回结果

可以使用 POST 方法请求网页并得到正确的返回结果

能够比较 Tomcat 和自己开发的服务器的返回结果的相似度

2.3 非功能性需求

服务器对读取的 WebContent(原老师给的是一个动态网页项目文件夹下的子目录)上升为一个动态网页项目,也就可以读取与 MyWebServer1.0 同级目录下的不同动态网页项目,且获取的 url 格式与 Tomcat 一样,MyWebContent1.0 是一个动态网页项目,all.html 是该项目里面的一个需要获取的页面。

例:http://localhost:8888/MyWebContent1.0/all.html

三、概要设计

3.1 系统总体设计

Web 服务器

总体上可以把 Web 服务器的代码分装成三个包:

Server 包封装服务器的主体流程:(VritualMachine)建立 socket 连接、(ProcessOne)过滤网、(ProcessTwo)发送(转译后)网页文件;

DataPool 包封装所有数据池,来降低类的耦合性,用 synchronized 来保证存取的数据安全:包括 ServletPool、JspPool、SessionPool、FilterPool;

Parameter 包封装了扩展 servlet-api.jar 的接口的所有类:

AFilterChain (implements FilterChain)、

Response(implements HttpServletResponse)、

Request(implements HttpServlet Request)、

Dispatcher(implements RequestDispatcher)、

Session(implements HttpSession);

测试工具

GET 方法,通过 socket 连接之后发送请求,然后接收网页返回的 Response,再去掉 GET 方法返回的头部,然后返回。

POST 方法,POST 通过模拟人登录浏览器获取信息来实现。有两种情况,如果页面中有 servlet 会先获取页面中的 servlet,然后设置 POST 的 header 和 method,并且设置成不马上转发和重定向,紧接着,如果调用函数时没有给表单的参数,则 POST 之后直接获取浏览器的返回结果,如果给了表单的参数,就会发送 POST 之后获取返回的重定向页面,然后设置对应的 GET 头,此时需要设置 JSESSIONID 以保证是同一个用户访问的页面,然后再获取浏览器的返回结果。

3.2 系统功能设计

Web 服务器

HTML:收到 socket 连接时,创一个线程读取 socket 输入流的报文头与体并创建 req 与 resp 对象,找到过滤链并执行过滤操作,最后写入报文头到 socket 输出流,并读取 HTML 文件作为报文体

Servlet:收到 socket 连接时,创一个线程读取 socket 输入流的报文头与体并创建 req 与 resp 对象,找到过滤链并执行过滤操作,到 ServletPool 找 servlet 对象,新生成一个调用服务器请求的方法,生成对应 HTML 文件,最后写入报文头到 socket 输出流,并读取 HTML 文件作为报文体

JSP:收到 socket 连接时,创一个线程读取 socket 输入流的报文头与体并创建 req 与 resp 对象,找到过滤链并执行过滤操作,从 JspPool 获取转译成 servlet 的对象,调用该对象的 GET/POST 方法,生成对应 HTML 文件,最后写入报文头到 socket 输出流,并读取 HTML 文件作为报文体

AFilterChain:FilterPool 里面包含每个项目的所有 Filter 对象,根据 req 的 url 可以找到匹配的 Filter 链。

Session:创建 req 对象的时候会为它设置一个 session,在最后写报文头的时候如果 req 的 header 没有“Cookie”,就在报文头里写上 Set-Cookie:sessionId。

页面跳转:req 的 getRequestDispatcher 会重新进入一个 ProcessTwo(其功能如下图所示);resp 的 sendRedirect(xxx)会直接在 socket 输出流设置状态 302,并设置 Location:xxx,然后使服务器发送新请求。

(图一)总体直观图

测试工具

客户端有两个属性,port 和 JSessionID,port 用于每次断开后的连接,因为获取完之后关闭 IO 流时会断开连接。JSessionID 初始化为 null,一旦收到了服务器给的 Cookie 就会设置 SessionID 来保证后续访问的时候是同一个用户。

sendGet:sendGet 会调用 setGetHeader 函数来设置 GET 头,然后发送,获取网页的 Response 后去掉头部的信息并返回收到的结果。

sendPost:sendPost 会调用 sendGet 来获取页面然后通过 getServletName 来获取 Servlet,并且如果带有参数,会调用 getProjectName 来获取项目名然后用来转发和重定向到别的页面,如果参数出错,就会获取一个转发后但是结果错误的网页。

WebClient 中的 connect 函数是用来测试该端口是否能够连接的。

CompareUtil 中的 compare 函数有两个参数,是要比较的两个文件所在的文件路径,然后返回一个 double 类型的值作为相似度。

FileUtil 用来写入文件。

WebUtil 用来根据所给的正则表达式然后获取页面中的标签。

四、详细设计

4.1 模块接口设计

Web 服务器

总类图

过滤链

如何只调用 AFilterChain 的 doFilter(req,resp)函数,就能实现全过滤 + 发送终版 HTML,需要 AfilterChain(差不多是一个链表),它里面包含一个 Filter 对象,并有一个 next 引用下一个 AfilterChain 对象。

public class AFilterChain implements FilterChain {
    private Filter cur;
    public AFilterChain next;
    public void doFilter(ServletRequest req, ServletResponse resp) {
        if(cur == null) {
            ProcessTwo p = new ProcessTwo(req,resp);
            handle();
        }
        else {
            if(next == null) {
                Filter t = cur;
                cur = null;
                next = null;
                doFilter(req, resp, this);
            }
            else {
                Filter t = cur;
                cur = next.cur;
                next = next.next;
                doFilter(req, resp, this);
            }
        }
    }
}
servlet

Servlet 执行后获得的 HTML 页面放入本工程的 html/pro/xxx 里面,然后通过当时建立连接的 socket 的输出流发送报文头 +html/pro/xxx 里面的东西。

jsp

JSP 都会被转成 servlet 类,这个类的.java 代码会被装入 jsp_servlet/pro/xxx 里面,调用这个转译的 servlet 形成的 HTML 页面也会装入与上面一样的文件里面。

测试工具

WebClient 提供了两个接口,sendGet 和 sendPost,两个接口用于发送 GET 请求和 POST 请求,sendPost 的第二个参数 Map 可以为 null,此时就不会有提交表单这个操作。返回值都为 String,也就是网页 Response 的结果。

CompareUtil 中提供了一个 compare 方法,可以比较两个文件(不是文件夹)的相似度,返回值为 Double。

FileUtil 中提供了 write 文件的方法,用于写入文件。

WebUtil 中提供了 getTag 的方法,用来找到 Web 页面中的各种标签,并返回一个 String,如果没找到就返回 null。

五、系统成果展示

5.1 模块 1 Web 服务器

得到过滤链的测试

JSP 转 servlet

测试输出

5.2 模块 2 测试工具

通过 GET 获取并保存到 txt 文件中的结果 测试用例不丰富,不能说明问题

更多的结果在 results 中,下面的是使用测试工具比较的结果,文件名的前缀是请求方式,后面带&是请求时的参数键值对


资源下载地址:https://download.csdn.net/download/sheziqiong/85706486
资源下载地址:https://download.csdn.net/download/sheziqiong/85706486

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
简单性 Java看起来设计得很像C++,但是为了使语言小和容易熟悉,设计者们把C++语言中许多可用的特征去掉了,这些特征是一般程序员很少使用的。例如,Java不支持goto语句,代之以提供break和continue语句以及异常处理。Java还剔除了C++的操作符过载(overload)和多继承特征,并且不使用主文件,免去了预处理程序。因为Java没有结构,数组和串都是对象,所以不需要指针。Java能够自动处理对象的引用和间接引用,实现自动的无用单元收集,使用户不必为存储管理问题烦恼,能更多的时间和精力花在研发上。 面向对象 Java是一个面向对象的语言。对程序员来说,这意味着要注意其中的数据和操纵数据的方法(method),而不是严格地用过程来思考。在一个面向对象的系统中,类(class)是数据和操作数据的方法的集合。数据和方法一起描述对象(object)的状态和行为。每一对象是其状态和行为的封装。类是按一定体系和层次安排的,使得子类可以从超类继承行为。在这个类层次体系中有一个根类,它是具有一般行为的类。Java程序是用类来组织的。 Java还包括一个类的扩展集合,分别组成各种程序包(Package),用户可以在自己的程序中使用。例如,Java提供产生图形用户接口部件的类(java.awt包),这里awt是抽象窗口工具集(abstract windowing toolkit)的缩写,处理输入输出的类(java.io包)和支持网络功能的类(java.net包)。 分布性 Java设计成支持在网络上应用,它是分布式语言。Java既支持各种层次的网络连接,又以Socket类支持可靠的流(stream)网络连接,所以用户可以产生分布式的客户机和服务器。 网络变成软件应用的分布运载工具Java程序只要编写一次,就可到处运行。 编译和解释性 Java编译程序生成字节码(byte-code),而不是通常的机器码。Java字节码提供对体系结构中性的目标文件格式,代码设计成可有效地传送程序到多个平台。Java程序可以在任何实现Java解释程序和运行系统(run-time system)的系统上运行。 在一个解释性的环境中,程序开发的标准“链接”阶段大大消失了。如果说Java还有一个链接阶段,它只是把新类装进环境的过程,它是增量式的、轻量级的过程。因此,Java支持快速原型和容易试验,它将导致快速程序开发。这是一个与传统的、耗时的“编译、链接和测试”形成鲜明对比的精巧的开发过程。 稳健性 Java原来是用作编写消费类家用电子产品软件的语言,所以它是被设计成写高可靠和稳健软件的。Java消除了某些编程错误,使得用它写可靠软件相当容易。 Java是一个强类型语言,它允许扩展编译时检查潜在类型不匹配问题的功能。Java要求显式的方法声明,它不支持C风格的隐式声明。这些严格的要求保证编译程序能捕捉调用错误,这就导致更可靠的程序。 可靠性方面最重要的增强之一是Java的存储模型。Java不支持指针,它消除重写存储和讹误数据的可能性。类似地,Java自动的“无用单元收集”预防存储漏泄和其它有关动态存储分配和解除分配的有害错误。Java解释程序也执行许多运行时的检查,诸如验证所有数组和串访问是否在界限之内。 异常处理是Java中使得程序更稳健的另一个特征。异常是某种类似于错误的异常条件出现的信号。使用try/catch/finally语句,程序员可以找到出错的处理代码,这就简化了出错处理和恢复的任务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shejizuopin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值