Tomcat 是一个的 Web Server,它也是一个满足 Servlet 规范的容器。我们想要在浏览器上运行自己的项目,那么就必须把web项目放到服务器中运行,而tomcat正是一个很好的webserver。
Java实现tomcat的功能的思路:tomcat的启动是基于socket服务,它支持 HTTP 协议!,将请求和响应封装成request和response。利用反射实例化具体的 Servlet 中,用io流将内容输出到浏览器。
项目目录
封装请求类:Myrequest.java
package com.tomcat;
import java.io.IOException;
import java.io.InputStream;
/**
* 封装请求对象
*通过输入流,对 HTTP 协议进行解析,
*拿到了 HTTP 请求头的方法以及 URL。
* @author黄钟亮hzl
*2018年12月15日
*/
public class MyRequest {
private String url;
private String method;
public MyRequest(InputStream inputStream) throws IOException {
String httpRequest = "";
byte[] httpRequestBytes = new byte[1024];
int length = 0;
if ((length = inputStream.read(httpRequestBytes))>0){
httpRequest = new String(httpRequestBytes , 0 ,length);
}
//http 请求协议
//System.out.println(httpRequest);
//通过字符串截取URL和请求方法
String httpHead = httpRequest.split("\n")[0];
method = httpHead.split("\\s")[0];
url = httpHead.split("\\s")[1];
System.out.println(this);
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public String toString() {
return "MyRequest [url=" + url + ", method=" + method + "]";
}
}
封装响应类:Myresponse.java
package com.tomcat;
import java.io.IOException;
import java.io.OutputStream;
/**
* 封装响应对象
* 基于HTTP协议的格式进行输出写入
* @author黄钟亮hzl
*2018年12月15日
*/
public class MyResponse {
private OutputStream outputStream;
public MyResponse(OutputStream outputStream){
this.outputStream = outputStream;
}
public void write(String content) throws IOException {
//http响应协议
StringBuffer httpResponse = new StringBuffer();
httpResponse.append("HTTP/1.1 200 OK\n").append("Content-Type:text/html\n")
.append("\r\n").append("<html><body>").append(content)
.append("</body><html>");
outputStream.write(httpResponse.toString().getBytes());
outputStream.close();
}
}
处理请求类:servlet.java
package com.tomcat;
/**
*
* Servlet 请求处理类
* @author黄钟亮hzl
*2018年12月15日
*/
public abstract class Servlet {
//Tomcat是满足Servlet规范的容器,所以提供了doget,dopost,service等常用的方法
public abstract void doGet(MyRequest myRequest ,MyResponse myResponse);
public abstract void doPost(MyRequest myRequest ,MyResponse myResponse);
public void service(MyRequest myRequest ,MyResponse myResponse){
if (myRequest.getMethod().equalsIgnoreCase("POST")){
doPost(myRequest,myResponse);
}else if (myRequest.getMethod().equalsIgnoreCase("GET")){
doGet(myRequest,myResponse);
}
}
}
servlet配置类:ServletMapping.java
package com.tomcat;
/**
* Servlet 配置
* @author黄钟亮hzl
*2018年12月15日
*/
public class ServletMapping {
private String servletName;
private String url;
private String clazz;
public ServletMapping(String servletName, String url, String clazz) {
this.servletName = servletName;
this.url = url;
this.clazz = clazz;
}
public String getServletName() {
return servletName;
}
public void setServletName(String servletName) {
this.servletName = servletName;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getClazz() {
return clazz;
}
public void setClazz(String clazz) {
this.clazz = clazz;
}
}
servlet配置类:ServletMappingConfig.java
相当于servlet.xml
package com.tomcat;
import java.util.ArrayList;
import java.util.List;
/**
*
* servlet配置相当于servlet.xml
* @author黄钟亮hzl
*2018年12月15日
*/
public class ServletMappingConfig {
public static List<ServletMapping> servletMappingList = new ArrayList<ServletMapping>();
static {
servletMappingList.add(new ServletMapping("helloWorld","/helloworld","com.tomcat.HelloWorldServlet"));
}
}
请求链接错误的servlet:ClassNotFoundServlet.java
package com.tomcat;
import java.io.IOException;
public class ClassNotFoundServlet extends Servlet {
@Override
public void doGet(MyRequest myRequest, MyResponse myResponse) {
try {
myResponse.write("<h1 style='color:red'>can not found this servlet<h1>");
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void doPost(MyRequest myRequest, MyResponse myResponse) {
try {
myResponse.write("<h1 style='color:red'>can not found this servlet<h1>");
} catch (IOException e) {
e.printStackTrace();
}
}
}
tomcat启动类:MiniTomat.java
package com.tomcat;
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;
/**
* 启动类
* @author黄钟亮hzl
*2018年12月15日
*/
/*Tomcat 的处理流程
把 URL 对应处理的 Servlet 关系形成,
解析 HTTP 协议,封装请求/响应对象,
利用反射实例化具体的 Servlet 进行处理即可。*/
public class MiniTocmat {
private int port = 80;
private Map<String,String> urlServletMap = new HashMap();
public MiniTocmat(int port){
this.port = port;
}
public void start() {
initServletMapping();
ServerSocket serverSocket =null;
try {
serverSocket = new ServerSocket(port);
System.out.println("MyTomcat is start....");
while (true){
Socket socket = serverSocket.accept();
// 解析 HTTP 协议,封装请求/响应对象
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
MyRequest myRequest = new MyRequest(inputStream);
MyResponse myResponse = new MyResponse(outputStream);
dispatch(myRequest,myResponse);
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void dispatch(MyRequest myRequest, MyResponse myResponse) {
String clazz = urlServletMap.get(myRequest.getUrl());
if (clazz==null) {
clazz = "com.tomcat.ClassNotFoundServlet";
}
//反射
try {
Class<Servlet> myServletClass = (Class<Servlet>) Class.forName(clazz);
Servlet myServlet = myServletClass.getDeclaredConstructor().newInstance();
myServlet.service(myRequest,myResponse);
} catch (Exception e) {
e.printStackTrace();
}
}
private void initServletMapping() {
for (ServletMapping servletMapping: ServletMappingConfig.servletMappingList) {
urlServletMap.put(servletMapping.getUrl(),servletMapping.getClazz());
}
}
public static void main(String[] args){
new MiniTocmat(80).start();
}
}
测试的servlet:helloworldservlet.java
package com.tomcat;
import java.io.IOException;
/**
* @author黄钟亮hzl
*2018年12月15日
*/
public class HelloWorldServlet extends Servlet{
public void doGet(MyRequest myRequest, MyResponse myResponse) {
try {
myResponse.write("hello word");
} catch (IOException e) {
e.printStackTrace();
}
}
public void doPost(MyRequest myRequest, MyResponse myResponse) {
try {
myResponse.write("hello word");
} catch (IOException e) {
e.printStackTrace();
}
}
}
作者:H钟L1998
来源:优快云
原文:https://blog.youkuaiyun.com/weixin_41528317/article/details/85014947
版权声明:本文为博主原创文章,转载请附上博文链接!