博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
模拟带Servlet技术的HTTP服务器的Java实现
阅读量:2492 次
发布时间:2019-05-11

本文共 5532 字,大约阅读时间需要 18 分钟。

上一篇文章说道, Web发展初期, 用户只能查看静态页面. 随着Web发展,只能显示静态页面的web显然已经不能满足大众的需求,所以出现了CGI和用Java编写的Servlet程序.

Servlet可以根据用户的请求动态的生成html页面,然后发给浏览器.

下面模拟一下这个过程:

  • HttpServer2类:服务器类,负责启动Http服务.
  • Servlet接口: 定义Servlet服务接口.
  • HelloServlet类:实现Servlet接口.用户提交请求时,HttpServer2将请求发给HelloServlet处理.处理完后动态生成页面返回给用户.
  • ServletRequest类: 封装用户的请求.交给HelloServlet处理.
  • ServletResponse类: 封装返回的响应.由HelloServlet返回.

HttpServer2类

服务器类,负责启动Http服务.

import java.io.*;import java.net.*;public class HttpServer2 {
private static final int port = 8088; private ServerSocket serverSocket = null; public HttpServer2() throws IOException { serverSocket = new ServerSocket(port); System.out.println("HTTPServer startup OK..."); } public void work() throws IOException { while (true) { try { Socket socket = serverSocket.accept(); ServletRequest request = new ServletRequest( socket.getInputStream()); ServletResponse response = new ServletResponse( socket.getOutputStream()); System.out.println("Receive request:\n" + request.getRequest()); String servletName = request.getServletName(); ​ ​//动态生成servlet Servlet servlet = (Servlet) Class.forName(servletName) .newInstance(); ​//调用servlet接口 servlet.init(); servlet.service(request, response); servlet.destroy(); socket.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void main(String[] args) throws IOException, InterruptedException { HttpServer2 httpServer = new HttpServer2(); httpServer.work(); }}

Servlet接口

定义Servlet服务接口.

public interface Servlet {    public void init();    public void service(ServletRequest req, ServletResponse res) throws Exception;    public void destroy();}

HelloServlet类

实现Servlet接口.用户提交请求时,HttpServer2将请求发给HelloServlet处理.处理完后动态生成页面返回给用户.

public class HelloServlet implements Servlet {
@Override public void init() { // TODO Auto-generated method stub System.out.println("servlet init "); } @Override public void service(ServletRequest req, ServletResponse res) throws Exception { // TODO Auto-generated method stub String contentType = req.getContentType(); String param = req.getParam(); ​//组装HTTP响应头 String header = res.assembleResponseHeader(contentType); ​//组装HTTP响应正文 String body = res.assembleResponseBody(param); ​//返回响应 res.write(header + body); } @Override public void destroy() { // TODO Auto-generated method stub System.out.println("servlet destroy "); }}

ServletRequest类

封装用户的请求.交给HelloServlet处理.

import java.io.IOException;import java.io.InputStream;public class ServletRequest {
private String request; private InputStream socketIn; private String URI; private String contentType; private String param; public ServletRequest(InputStream socketIn) throws IOException { // TODO Auto-generated constructor stub this.socketIn = socketIn; this.request = _getRequest(); this.URI = _getURI(); this.contentType = _getContentType(); this.param = _getParam(); } public String getRequest() { return request; } public String getURI() { return URI; } public String getContentType() { return contentType; } public String getParam() { return param; } private String _getRequest() throws IOException { int size = socketIn.available(); byte[] requestBuff = new byte[size]; socketIn.read(requestBuff); return new String(requestBuff); } ​//获得要调用servlet的类名 public String getServletName(){ return URI.substring(URI.indexOf("/") + 1, URI.indexOf("?")); } private String _getURI() { String firstLine = request.substring(0, request.indexOf("\r\n")); String[] parts = firstLine.split(" "); return parts[1]; } private String _getContentType() { /* 决定HTTP响应正文的类型 */ return "html"; }//获得请求参数 private String _getParam() { String paramString = URI.substring(URI.indexOf("?") + 1); String[] paramPairs = paramString.split("="); return paramPairs[1]; }}

ServletResponse类

封装返回的响应.由HelloServlet返回.

import java.io.IOException;import java.io.OutputStream;public class ServletResponse {
private OutputStream outputStream; public ServletResponse(OutputStream outputStream) { // TODO Auto-generated constructor stub this.outputStream = outputStream; } public String assembleResponseHeader(String contentType) { /* 创建HTTP响应结果 */ // HTTP响应的第一行 String responseFirstLine = "HTTP/1.1 200 OK\r\n"; // HTTP响应头 String responseHeader = "Content-Type:" + contentType + "\r\n\r\n"; return responseFirstLine + responseHeader; } public String assembleResponseBody(String param) { String content = "

Hello:" + param + "

"; String title = "HelloWorld"; String body = "" + title + content + ""; return body; } public void write(String res) throws IOException { outputStream.write(res.getBytes()); }}

测试

在chrome浏览器输入.

即用户请求的参数是tom,要调用HelloServlet. (在实际的servlet实现中,是用一个web.xm配置文件实现URI到servlet的映射.)

这里写图片描述

servlet解析出来后组装成html返回给浏览器.显示为Hello:tom

这里写图片描述

你可能感兴趣的文章
jQuery 学习笔记(jQuery: The Return Flight)
查看>>
Java中常用的测试工具JUnit
查看>>
PHP图形图像的典型应用 --常用图像的应用(验证码)
查看>>
Robot Framework-Ride界面介绍及库的添加
查看>>
IntelliJ IDEA 连接数据库 详细过程
查看>>
redis完全攻略
查看>>
D3---01基础的柱状图制作(转)
查看>>
Time-Varying Mesh Compression
查看>>
SocketServer源码学习(二)
查看>>
编写DLL所学所思(1)——导出函数
查看>>
POJ3006-Dirichlet's Theorem on Arithmetic Progressions
查看>>
QT分页控件,开源,供大家使用
查看>>
005.LVM删除
查看>>
Hibernate 简介(百度)
查看>>
深入理解 KVC\KVO 实现机制 — KVC
查看>>
Android develop 国际化
查看>>
oralce之存储过程
查看>>
Redis源代码分析之sds, 动态数组
查看>>
macOS下Apache+nginx+mysql+php多版本切换的配置
查看>>
写在前面
查看>>