上一篇文章说道, 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解析出来后组装成html返回给浏览器.显示为Hello:tom
时间: 2024-11-01 02:16:35