tomcat探究二搭建简单的servlet容器
说明
HttpServer:容器服务入口,监听一个端口
Request:对请求报文做处理,获取http请求报文第一行的资源路径
Response:延续 探究一 的内容
Servlet:自定义servlet
ServletProcessor:请求servlet资源的处理
TestControllerServlet:模拟测试类,实现servlet接口
代码
HttpServer
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class HttpServer {
//静态资源的路径
public static final String WEB_ROOT = "D:\\tomcat_servlet\\static";
//关闭命令
private static final String SHUTDOWN_COMMAND = "/SHUTDOWN";
//是否关闭socket
private boolean shutdown = false;
public static void main(String[] args) {
HttpServer server = new HttpServer();
server.await();
}
public void await() {
ServerSocket serverSocket = null;
int port = 8080;
try {
serverSocket = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
while(!shutdown) {
Socket socket = null;
InputStream in = null;
OutputStream out = null;
try {
socket = serverSocket.accept();
in = socket.getInputStream();
out = socket.getOutputStream();
Request request = new Request(in);
request.parse();
if(request.getUri() == null ) {
socket.close();
continue;
}
Response response = new Response(out, request);
if(request.getUri().startsWith("/servlet/")) {
//处理servlet
new ServletProcessor().process(request, response);
}else {
//静态资源
response.sendStaticResource();
}
socket.close();
shutdown = request.getUri().equals(SHUTDOWN_COMMAND);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Request
import java.io.InputStream;
public class Request {
private InputStream in;
private String uri = null;
private static final int BUFFER_SIZE = 2048;
public Request (InputStream in){
this.in = in;
}
public void parse() {
StringBuffer request = new StringBuffer(BUFFER_SIZE);
int i = 0;
byte[] buffer = new byte[BUFFER_SIZE];
try {
i = in.read(buffer);
} catch (Exception e) {
e.printStackTrace();
i = -1;
}
for(int j = 0;j < i;j++) {
request.append((char)buffer[j]);
}
System.out.println(request.toString());
uri = parseUri(request.toString());
}
private String parseUri(String requestString) {
int index1,index2;
index1 = requestString.indexOf(' ');
if(index1 != -1 ) {
index2 = requestString.indexOf(' ',index1 + 1);
if(index2 > index1) {
return requestString.substring(index1 + 1, index2);
}
}
return null;
}
public String getUri() {
return uri;
}
}
Response
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
public class Response {
private static final int BUFFER_SIZE = 1024;
Request request;
OutputStream out;
public Response(OutputStream out,Request request) {
this.out = out;
this.request = request;
}
public void sendStaticResource() {
byte[] bytes = new byte[BUFFER_SIZE];
FileInputStream fin = null;
try {
File file = new File(HttpServer.WEB_ROOT + File.separator + request.getUri());
if(file.exists()) {
fin = new FileInputStream(file);
String pre = "HTTP/1.1 200 ok\r\n\r\n" ;
out.write(pre.getBytes());
int ch = fin.read(bytes, 0, BUFFER_SIZE);
while(ch != -1) {
out.write(bytes,0,ch);
ch = fin.read(bytes, 0, BUFFER_SIZE);
}
out.flush();
}else {
/**
* 文件不存在
*/
String errorMessage = "HTTP/1.1 404 File Not Found\r\n"
+ "Content-type: text/html\r\n"
+ "Content-Length: 23\r\n"
+"\r\n"
+"<h1>File Not Found</h1>";
out.write(errorMessage.getBytes());
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if(fin != null) {
try {
fin.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Servlet
public interface Servlet {
public void init();
public void service(Request request,Response response);
public void destroy();
}
ServletProcessor
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
public class ServletProcessor {
public void process(Request request,Response response) {
String uri = request.getUri();
String servletName = uri.substring(uri.lastIndexOf("/")+1);
ClassLoader loader = null;
try {
URL[] urls = new URL[1];
File classPath = new File(System.getProperty("user.dir"));
classPath = new File("D:java\\mytomcat\\classes\\");
URL classUri = classPath.toURL();
urls[0] = classUri;
loader = new URLClassLoader(urls);
// loader = this.getClass().getClassLoader();
} catch (Exception e) {
e.printStackTrace();
}
Class myClass = null;
try {
/**
* TestControllerServlet包名是serveletserver --暂时先这样
*/
myClass = loader.loadClass("serveletserver."+servletName);
}catch (Exception e) {
e.printStackTrace();
}
Servlet servlet = null;
try {
servlet = (Servlet) myClass.newInstance();
servlet.service(request, response);
} catch (Exception e) {
e.printStackTrace();
}
}
}
TestControllerServlet
在同一个包还可以创建其他类似的类
import java.io.IOException;
public class TestControllerServlet implements Servlet{
@Override
public void init() {
}
@Override
public void destroy() {
}
@Override
public void service(Request request, Response response) {
String message = "HTTP/1.1 200 ok\r\n\r\nhello";
try {
response.out.write(message.getBytes());
response.out.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
请求测试
http://localhost:8080/servlet/TestControllerServlet