使用socket实现一个自己的Tomcat
创建一个请求的类,获取方法和路径
public class MyRequest {
private String method;
private String url;
public String getUrl() {
return url;
}
public String getMethod() {
return 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);
}
String line = content.split("\\n")[0];
String [] arr = line.split("\\s");
this.method = arr[0];
this.url = arr[1].split("\\?")[0];
}catch (Exception e){
e.printStackTrace();
}
}
}
新建个 相应的类
public class MyResponse {
private OutputStream outputStream;
public MyResponse(OutputStream outputStream){
this.outputStream=outputStream;
}
public void write(String s) throws Exception{
//用到的是http协议,输出也要准寻http
StringBuilder sb=new StringBuilder();
sb.append("HTTP/1.1 200 OK")
.append("Content-Type: text/html;\n")
.append("\r\n")
.append(s);
outputStream.write(sb.toString().getBytes());
}
}
新建个servlet 抽象类 定义公共的get 和post方法调用
public abstract class MyServlet {
public void service(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);
}
@Override
public void doPost(MyRequest request, MyResponse response) throws Exception {
response.write("This is my first test html!");
}
}
需要个web.properties文件进行配置路径
servlet.one.url=/firstServlet.do
servlet.one.className=com.netty.demo.tomcatDemo.servlet.FirstServlet
servlet.two.url=/secondServlet.do
servlet.two.className=com.netty.demo.tomcatDemo.servlet.SecondServlet
最后实现的就是 tomcat 的类
public class MyTomcat {
/**
* 1、配置好启动端口,默认8080 ServerSocket IP:localhost
* 2、配置web.xml 自己写的Servlet继承HttpServlet
* servlet-name servlet-class url-pattern
* 3、读取配置,url-pattern 和 Servlet建立一个映射关系
* Map servletMapping
* 4、HTTP请求,发送的数据就是字符串,有规律的字符串(HTTP协议)
* 5、从协议内容中拿到URL,把相应的Servlet用反射进行实例化
* 6、调用实例化对象的service()方法,执行具体的逻辑doGet/doPost方法
* 7、做出相应 Request(InputStrean)/Response(OutputStrean)
*/
//1、配置好启动端口,默认8080 ServerSocket IP:localhost
private int port =8080;
private ServerSocket serverSocket;
private Map<String , MyServlet> servletMap=new HashMap<>();
private Properties webxml=new Properties();
private void init(){
try{
//加载web.xml文件,同时初始化 ServletMapping对象
String WEB_INF=this.getClass().getResource("/").getPath();
FileInputStream 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);
String className=webxml.getProperty(servletName+".className");
//单实例
MyServlet obj=(MyServlet)Class.forName(className).newInstance();
servletMap.put(url,obj);
}
}
}catch (Exception e){
e.printStackTrace();
}
}
public void start(){
//1、加载配置文件,初始化ServeltMapping
init();
try{
serverSocket=new ServerSocket(this.port);
System.out.println("MyTomcat 已启动,监听的端口为:"+port);
//2、等待用户请求,用一个死循环来等待用户请求
while (true){
Socket client=serverSocket.accept();
//4、HTTP请求,发送的数据就是字符串,有规律的字符串(HTTP协议)
process(client);
}
}catch (Exception e){
e.printStackTrace();
}
}
private void process(Socket client) throws Exception{
InputStream in=client.getInputStream();
OutputStream out=client.getOutputStream();
MyRequest request=new MyRequest(in);
MyResponse response=new MyResponse(out);
String url=request.getUrl();
if(servletMap.containsKey(url)){
servletMap.get(url).service(request,response);
}else{
response.write("404 Not Found This Url!");
}
out.flush();
out.close();
in.close();
client.close();
}
//启动一个tomcat
public static void main(String[] args) {
new MyTomcat().start();
}
}
最后直接启动后,进行访问 /firstServlet.do
http://localhost:8080/secondServlet.do
http://localhost:8080/secondServlet.do