模仿tomcat,简单实现一个类似的servlet容器
配置文件(类似web.xml)
web.properties
serlvet.one.url=/firstServlet.do
serlvet.one.className=com.aiso.design.demo.tomcat.servlet.FirstServlet
#serlvet.two.url=/firstServlet.do
#servlet.two.className=com.aiso.design.demo.tomcat.servlet.SecServlet
核心服务类
package com.aiso.design.demo.tomcat.catalina;
import com.aiso.design.demo.tomcat.http.MyRequest;
import com.aiso.design.demo.tomcat.http.MyResponse;
import com.aiso.design.demo.tomcat.http.MyServlet;
import com.aiso.design.demo.tomcat.servlet.FirstServlet;
import org.apache.catalina.servlet4preview.http.ServletMapping;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Pattern;
public class MyTomcat {
private int port = 8080;
ServerSocket serverSocket;
private Map<Pattern, Class<?>> servletMapping = new HashMap<Pattern, Class<?>>();
private Properties webxml = new Properties();
private String WEB_INF = this.getClass().getResource("/").getPath();
public MyTomcat() {
start();
}
public MyTomcat(int port) {
this.port = port;
}
//容器启动之前 加载所有的 配置文件
private void init() {
FileInputStream fis = null;
try {
fis = new FileInputStream(WEB_INF + "web.properties");
webxml.load(fis);
for (Object k :
webxml.keySet()) {
String key = k.toString();
if (key.endsWith(".url")) {
String servletName = key.replaceAll("\\.url$", "");
String url = webxml.getProperty(key);
Pattern pattern = Pattern.compile(url);
String className = webxml.getProperty(servletName + ".className");
Class<?> servletClass = Class.forName(className);
servletMapping.put(pattern, servletClass);
}
}
} catch (Exception e) {
}
}
//等待用户请求
private void process(Socket client) throws Exception {
InputStream is = null;
OutputStream out = null;
MyRequest request = new MyRequest(is);
MyResponse response = new MyResponse(out);
try {
is = client.getInputStream();
out = client.getOutputStream();
//读取web.xml 获取servlet
//利用反射new
String url = request.getUrl();
boolean isPattern = false;
for (Map.Entry<Pattern, Class<?>> entry :
servletMapping.entrySet()) {
if (entry.getKey().matcher(url).matches()) {
MyServlet servlet = (MyServlet) entry.getValue().newInstance();
servlet.serivce(request, response);
isPattern = true;
}
}
if (!isPattern) {
response.write("404 - Not Found ");
}
System.out.println("-----------------------");
} catch (Exception e) {
response.write("500," + e.getMessage());
} finally {
if (null != is) {
is.close();
}
if (null != is) {
out.close();
}
if (null != is) {
client.close();
}
}
}
public void start() {
init();
try {
serverSocket = new ServerSocket(this.port);
System.out.println("mytomcat 已启动,监听端口是" + port);
} catch (IOException e) {
e.printStackTrace();
System.out.println("mytomcat 启动失败," + e.getMessage());
return;
}
while (true) {
try {
Socket client = serverSocket.accept();
process(client);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
http 请求封装
package com.aiso.design.demo.tomcat.http;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
public class MyRequest {
private String method;
public String url;
public void setUrl(String url) {
this.url = url;
}
public void setMethod(String method) {
this.method = method;
}
public MyRequest(InputStream inputStream) {
try {
//从http协议中解析客户端带过来的信息
String content = "";
byte[] buff = new byte[1024];
int len = 0;
if ((len = inputStream.read(buff)) > 0) {
content = new String(buff, 0, len);
}
System.out.println(content);
String line = content.split("\\n")[0];
String[] arr = line.split("\\s");
this.method = arr[0];
this.url = arr[1].split("\\?")[0];
} catch (IOException e) {
e.printStackTrace();
}
}
public String getMethod() {
return null;
}
public String getUrl() {
return null;
}
public Map<String, String> getParameter() {
return null;
}
}
http 响应封装
package com.aiso.design.demo.tomcat.http;
import java.io.OutputStream;
public class MyResponse {
private OutputStream os;
public MyResponse(OutputStream outputStream) {
this.os = os;
}
public void write(String outStr) throws Exception {
os.write(outStr.getBytes());
os.flush();
}
}
servlet
package com.aiso.design.demo.tomcat.http;
public abstract class MyServlet {
public void serivce(MyRequest request, MyResponse response) throws Exception {
if ("GET".equalsIgnoreCase(request.getMethod())) {
doGet(request, response);
} else {
doPost(request,response);
}
}
public abstract void doGet(MyRequest request, MyResponse response) throws Exception;
public abstract void doPost(MyRequest request, MyResponse response) throws Exception;
}
测试servlet
public class FirstServlet extends MyServlet {
@Override
public void doGet(MyRequest request, MyResponse response) throws Exception {
this.doPost(request, response);
response.write("hello world " + ", is" + request.getMethod());
}
@Override
public void doPost(MyRequest request, MyResponse response) throws Exception {
//处理逻辑
response.write("hello world");
}
}