0
点赞
收藏
分享

微信扫一扫

模拟带Servlet技术的HTTP服务器的Java实现


上一篇文章说道, 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 = "<body><h1>Hello:" + param + "</h1></body>";
String title = "<head><title>HelloWorld</title></head>";
String body = "<html>" + title + content + "</html>";
return body;
}

public void write(String res) throws IOException {
outputStream.write(res.getBytes());
}

}

测试

在chrome浏览器输入​​http://localhost:8088/HelloServlet?username=tom​​.
即用户请求的参数是tom,要调用HelloServlet. (在实际的servlet实现中,是用一个web.xm配置文件实现URI到servlet的映射.)


模拟带Servlet技术的HTTP服务器的Java实现_接口

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

模拟带Servlet技术的HTTP服务器的Java实现_动态_02


举报

相关推荐

0 条评论