`
zc985552943
  • 浏览: 288018 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
Babe4ca6-5e6f-33aa-9078-762ee3ccfb7e
云计算--hadoop
浏览量:11560
5e98c2c1-2a82-3388-bc80-7fca0170bb12
redis解说
浏览量:26731
088014c7-4d3f-39ce-b72e-4ebe7046a134
MongoDB读书笔记
浏览量:15693
D2b74847-c860-3e26-96fe-3fa4498d6348
Maven读书笔记
浏览量:26794
688db20f-402d-3a1d-8188-d6153d6c7465
Java通信
浏览量:13451
社区版块
存档分类
最新评论

浅析Tomcat(一)

阅读更多
想必大家都知道Tomcat其实就是servlet容器。负责servlet前期的准备工作。在这里简单用代码模拟一下Tomcat的工作。
首先牵涉到网络,那么网络编程是少不了的。
1.这个类就是一个servlet服务的工具,程序从这里开始
package com.arz.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class ServletServer {
	
	private ServerSocket serverSocket;
	private int port;
	private boolean shutDown;
	
	public ServletServer (int port){
		this.port = port;
	}
	
	public void startServer(){
		try{
			serverSocket = new ServerSocket(port);
		}catch(IOException e){
			System.out.println("监听"+port+"失败!");
			System.exit(0);
		}
		while(!shutDown){
			try{
				//监听着8080端口
				Socket socket = serverSocket.accept();
				
				//实例一个Runnable接口类,在这里面运行全部的核心工作
				DispatchSocket dispatchSocket = new DispatchSocket(socket);
				
				//启动Runnable中的run()方法
				new Thread(dispatchSocket).start();
			}catch(IOException e){
				System.out.println("客户端出了问题");
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args){
		ServletServer server = new ServletServer(8080);
		server.startServer();
	}
	
	public boolean isShutDown(){
		return shutDown;
	}
	
	public void setShutDown(boolean shutDown){
		this.shutDown = shutDown;
	}
}


2.创建DispatchSocket这个类是为了满足Tomcat的多线程而产生的。有了这个类“Tomcat”就可以同时被多个访问了
package com.arz.server;

import java.io.IOException;
import java.net.Socket;

import com.arz.servlet.Servlet;
import com.arz.servlet.ServletMapping;
import com.arz.servlet.TestServlet;
import com.arz.servlet.WebApp;

public class DispatchSocket implements Runnable {
	
	private Socket socket;
	
	public DispatchSocket(Socket socket){
		this.socket = socket;
	}
	@Override
	public void run() {
		try{
			System.out.println("客户端是:"+socket.getRemoteSocketAddress());
			
			//实例request,可以跟踪查看Request类,将socket类的输入流交给request。可以看做是HttpServletRequest
			Request request = new Request(socket.getInputStream(),8080);
			
			//实例response,可以跟踪查看Response类,将socket类的输出流交给response。结果将会输出到网页。可以看做是HttpServletResponse
			Response response = new Response(socket.getOutputStream());
			
			//*****************这里是直接运行Servlet类的service方法*****************
			//将这个类看做是HttpServlet
			Servlet servlet = new TestServlet();
			//调用我们写的service()方法
			servlet.service(request, response);
			
			//*****************这里是我们解析web.xml得到的servlet对象,和上面是并行的*****************
			//解析web.xml的类,并且将对象的对应关系包装好
			WebApp webApp = WebApp.getWebApp();
			
			String urlPattern = request.getUrlPattern();
			
			ServletMapping mapping = webApp.getServletMappings().get(urlPattern);
			
			if(mapping != null){
				String servletName = mapping.getServletName();
				Servlet servlet1 = webApp.getServletContext().getServlet(servletName);
				if(servlet1 != null){
					servlet1.service(request, response);
				}else{
					response.println("没有获得Servlet");
				}
			}else{
				response.print("你请求的url错误,该url不正确。没有找到相应的页面!");
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			closeSocket(socket);
		}
		
	}
	
	public void closeSocket(Socket socket){
		if(socket != null){
			try{
				socket.getOutputStream().flush();
				socket.close();
			}catch(IOException e){
				e.printStackTrace();
			}
		}
	}
}


3.大家应该知道java在servlet编程中只是提供了类的接口,具体的实现是交给服务商完成的。作为比较优秀的服务器Tomcat自然也要实现java定义的servlet类例如HttpServletRequest,下面是HttpServletRequest的模拟代码。当然真正的HttpServletRequest要复杂的多的多
package com.arz.server;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

public class Request {
    
    private int port;
    private String host;
    private String urlPattern;
    private Map<String,String> map = new HashMap<String,String>();
    private String method;
    
    private String headInfo;
    private InputStream inStream;
    protected Request(InputStream inStream,int port) {
        this.inStream = inStream;
        this.port = port;
        parseRequestHead();
    }
    
    private void parseRequestHead(){
        byte[] buf = new byte[1024];
        try{
            inStream.read(buf);
            headInfo = new String(buf);
            System.out.println(headInfo);
            method = headInfo.substring(0,headInfo.indexOf("/")).trim();
            System.out.println("请求方式:"+method);
            host = headInfo.substring(headInfo.indexOf("Host:")+5,headInfo.indexOf(":"+port)).trim();
            System.out.println("请求地址:"+host);
            //??
            if(method.equalsIgnoreCase("get")){
                parseGetString();
            }else if (method.equalsIgnoreCase("post")){
                parsePostString();
            }
        }catch(IOException e){
            e.printStackTrace();
        }
    }
    
    private void parsePostString(){
        urlPattern = headInfo.substring(5, headInfo.indexOf("HTTP/")).trim();
        String dataString = headInfo.substring(headInfo.lastIndexOf("\r\n")).trim();
        //??
        StringTokenizer st = new StringTokenizer(dataString,"&");
        
        while(st.hasMoreTokens()){
            String[] ss = st.nextToken().split("=");
            map.put(ss[0], ss[1]);
        }
    }
    
    private void parseGetString(){
        String url = headInfo.substring(4, headInfo.indexOf("HTTP/"));
        if(url.indexOf("?")==-1){
            urlPattern = url.trim();
        }else{
            urlPattern = url.substring(0, url.indexOf("?")).trim();
            String dataString = url.substring(url.indexOf("?")+1).trim();
            StringTokenizer st = new StringTokenizer(dataString,"&");
            while(st.hasMoreTokens()){
                String[] ss = st.nextToken().split("=");
                map.put(ss[0], ss[1]);
            }
        }
    }
    public int getPort() {
        return port;
    }
    public void setPort(int port) {
        this.port = port;
    }
    public String getHost() {
        return host;
    }
    public void setHost(String host) {
        this.host = host;
    }
    public String getUrlPattern() {
        return urlPattern;
    }
    public void setUrlPattern(String urlPattern) {
        this.urlPattern = urlPattern;
    }
    public String getMethod() {
        return method;
    }
    public void setMethod(String method) {
        this.method = method;
    }
    public String getHeadInfo() {
        return headInfo;
    }
    public void setHeadInfo(String headInfo) {
        this.headInfo = headInfo;
    }
    
    public String getParameter(String name){
        if(map != null && map.size() > 0){
            return (String)map.get(name);
        }
        return null;
    }
    
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics