不知道大家是否还记得前面我一篇文章中的那份简历,神一样的存在。很多人认为很难,但其实你也可以做到。走不一样的路,今天我们一起手把手的撸一个 Tomcat 吧。
你要撸一个 Tomcat,你首先得知道 Tomcat 干了哪些事。我们撸的简单点,就是把 Tomcat 解析 Http 协议,封装 Request 和 Response,调用 Servlet 这一块核心给搞出来。
明白这一点后,我们先来写一个 Socket,监听端口,解析封装请求和响应对象。
public class TomcatMain {
// 存储 Servlet,相当于在 web.xml 中配置 Servlet
private Map<String, String> servletMaps = new HashMap<>();
public TomcatMain(){
loadXml();
}
private void loadXml(){
servletMaps.put("/xttblog","com.xttblog.tomcat.HelloServlet");
}
public void start() {
ServerSocket server = null;
try {
server = new ServerSocket(8089);
System.out.println("server on port 8080 is running...");
while (true) {
Socket client = server.accept();
requestAndResponseHandle(new XttblogRequest(client.getInputStream()),
new XttblogResponse(client.getOutputStream()));
client.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void requestAndResponseHandle(XttblogRequest request,
XttblogResponse response) {
String className = servletMaps.get(request.getUrl());
if (className != null) {
try {
Class cls = Class.forName(className);
XttblogServlet myServlet = (XttblogServlet) cls.newInstance();
myServlet.service(request, response);
} catch (Exception e){
e.printStackTrace();
}
}
}
public static void main(String[] args) {
TomcatMain tomcat = new TomcatMain();
tomcat.start();
}
}
代码很简单,读取 Web.xml 这一块忽略,相当于直接读取到了 Map 中。
然后是请求 Request 部分的代码。
public class XttblogRequest {
private String url;
private String method;
public XttblogRequest(InputStream is) throws IOException {
byte[] content = new byte[1024];
int readLen = is.read(content);
if (readLen > 0) {
String s = new String(content, 0, readLen);
String[] ss = s.split("//s");
url = ss[1];
switch (ss[0]) {
case "GET": {
method = "GET";
break;
} case "POST": {
method = "POST";
break;
}
}
}
}
public String getUrl() {
return url;
}
public String getMethod() {
return method;
}
}
再接着封装 Response。
public class XttblogResponse {
private OutputStream os;
public XttblogResponse(OutputStream os) {
this.os = os;
}
public void write(String content) throws IOException {
StringBuilder sbd = new StringBuilder(128);
String line = "/r/n";
sbd.append("HTTP/1.0 200 ").append(line)
.append("Content-Type:text/html").append(line)
.append(line)
.append("<html><body>")
.append(content)
.append("</body></html>");
os.write(sbd.toString().getBytes());
}
public void close() throws IOException {
os.close();
}
}
接着是 XttblogServlet 接口。
public abstract class XttblogServlet {
public abstract void doGet(XttblogRequest request,
XttblogResponse response) throws Exception;
public abstract void doPost(XttblogRequest request,
XttblogResponse response) throws Exception;
public void service(XttblogRequest request,
XttblogResponse response) throws Exception{
String method = request.getMethod();
switch (method) {
case "GET": {
doGet(request, response);
break;
}case "POST": {
doPost(request, response);
break;
}
}
}
}
最后一步,写个 Servlet 测试我们的 Tomcat。
public class HelloServlet extends XttblogServlet{
@Override
public void doGet(XttblogRequest request,
XttblogResponse response) throws Exception {
String say = request.getMethod() + " request,www.xttblog.com say hello";
System.out.println(say);
response.write(say);
}
@Override
public void doPost(XttblogRequest request,
XttblogResponse response) throws Exception {
String say = request.getMethod() + " request,www.xttblog.com say hello";
System.out.println(say);
response.write(say);
}
}
至此,代码全部撸完。我们 main 方法启动项目。浏览器里输入 http://localhost:8089/xttblog,请求响应完美支持。
上面的代码很简单,但 Tomcat 并不简单。Tomcat 还有很多功能,里面也用到了很多设计模式,线程池,集群,虚拟目录等各种功能。想要了解更多,可以阅读 Tomcat 源码或者扫码下方海报上的二维码,我们一起在极客时间上学习 Tomcat。
: » 手把手教你撸一个 Tomcat 服务器
原创文章,作者:254126420,如若转载,请注明出处:https://blog.ytso.com/252106.html