• tomcat探究二搭建简单的servlet容器


    说明

    HttpServer:容器服务入口,监听一个端口
    Request:对请求报文做处理,获取http请求报文第一行的资源路径
    Response:延续 探究一 的内容
    Servlet:自定义servlet
    ServletProcessor:请求servlet资源的处理
    TestControllerServlet:模拟测试类,实现servlet接口

    代码

    HttpServer

    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class HttpServer {
    	//静态资源的路径
    	public  static final String WEB_ROOT = "D:\\tomcat_servlet\\static";
    	//关闭命令
    	private static final String SHUTDOWN_COMMAND = "/SHUTDOWN";
    	//是否关闭socket
    	private boolean shutdown = false;
    	
    	public static void main(String[] args) {
    		HttpServer server = new HttpServer();
    		server.await();
    	}
    	
    	public void await() {
    		ServerSocket serverSocket = null;
    		
    		int port = 8080;
    		
    		try {
    			serverSocket = new ServerSocket(port);
    		} catch (IOException  e) {
    			e.printStackTrace();
    		}
    		
    		while(!shutdown) {
    			Socket socket = null;
    			InputStream in = null;
    			OutputStream out = null;
    			
    			try {
    				socket = serverSocket.accept();
    				in = socket.getInputStream();
    				out = socket.getOutputStream();
    				
    				Request request = new Request(in);
    				request.parse();
    				
    				
    				
    				if(request.getUri() == null ) {
    					socket.close();
    					continue;
    				}
    				
    				Response response = new Response(out, request);
    				
    				if(request.getUri().startsWith("/servlet/")) {
    					//处理servlet
    					new ServletProcessor().process(request, response);
    				}else {
    					//静态资源
    					response.sendStaticResource();
    				}
    				
    				socket.close();
    				
    				shutdown = request.getUri().equals(SHUTDOWN_COMMAND);
    				
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    		}
    	}
    }
    

    Request

    import java.io.InputStream;
    
    public class Request {
    	private InputStream in;
    	private String uri = null;
    	private static final int BUFFER_SIZE = 2048;
    	
    	public Request (InputStream in){
    		this.in = in;
    	}
    	
    	public void parse() {
    		StringBuffer request = new StringBuffer(BUFFER_SIZE);
    		
    		int i = 0;
    		byte[] buffer = new byte[BUFFER_SIZE];
    		
    		try {
    			i = in.read(buffer);
    		} catch (Exception e) {
    			e.printStackTrace();
    			i = -1;
    		}
    		
    		for(int j = 0;j < i;j++) {
    			request.append((char)buffer[j]);
    		}
    		
    		System.out.println(request.toString());
    		
    		uri = parseUri(request.toString());
    	}
    	
    	
    	private String parseUri(String requestString) {
    		int index1,index2;
    		index1 = requestString.indexOf(' ');
    		if(index1 != -1 ) {
    			index2 = requestString.indexOf(' ',index1 + 1);
    			if(index2 > index1) {
    				return requestString.substring(index1 + 1, index2);
    			}
    		}
    		
    		return null;
    	}
    	
    	public String getUri() {
    		return uri;
    	}
    }
    

    Response

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    
    public class Response {
    	
    	private static final int BUFFER_SIZE = 1024;
    			
    	Request request;
    	
    	OutputStream out;
    	
    	public Response(OutputStream out,Request request) {
    		this.out = out;
    		this.request = request;
    	}
    	
    	public void sendStaticResource() {
    		byte[] bytes = new byte[BUFFER_SIZE];
    		
    		FileInputStream fin = null;
    		
    		try {
    			File file = new File(HttpServer.WEB_ROOT + File.separator + request.getUri());
    			if(file.exists()) {
    				fin = new FileInputStream(file);
    				String pre = "HTTP/1.1 200 ok\r\n\r\n" ;
    				out.write(pre.getBytes());
    				int ch = fin.read(bytes, 0, BUFFER_SIZE);
    				while(ch != -1) {
    					out.write(bytes,0,ch);
    					ch = fin.read(bytes, 0, BUFFER_SIZE);
    				}
    				out.flush();
    			}else {
    				/**
    				 * 文件不存在
    				 */
    				String errorMessage = "HTTP/1.1 404 File Not Found\r\n"
    						+ "Content-type: text/html\r\n"
    						+ "Content-Length: 23\r\n"
    						+"\r\n"
    						+"

    File Not Found

    "
    ; out.write(errorMessage.getBytes()); } } catch (Exception e) { e.printStackTrace(); }finally { if(fin != null) { try { fin.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }

    Servlet

    public interface Servlet {
    
    	public void init();
    	
    	public void service(Request request,Response response);
    	
    	public void destroy();
    	
    }
    

    ServletProcessor

    import java.io.File;
    import java.net.URL;
    import java.net.URLClassLoader;
    
    public class ServletProcessor {
    	
    	public void process(Request request,Response response) {
    		String uri = request.getUri();
    		
    		String servletName = uri.substring(uri.lastIndexOf("/")+1);
    		
    		ClassLoader loader = null;
    		
    		try {
    			URL[] urls = new URL[1];
    			File classPath = new File(System.getProperty("user.dir"));
    			classPath = new File("D:java\\mytomcat\\classes\\");
    			URL classUri = classPath.toURL();
    			urls[0] = classUri;
    			loader = new URLClassLoader(urls);
    //			loader = this.getClass().getClassLoader();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		
    		Class myClass = null;
    		
    		try {
    			/**
    			* TestControllerServlet包名是serveletserver --暂时先这样
    			*/
    			myClass = loader.loadClass("serveletserver."+servletName);
    	    }catch (Exception e) {
    			e.printStackTrace();
    		}
    		
    		Servlet servlet = null;
    		try {
    			servlet = (Servlet) myClass.newInstance();
    			
    			servlet.service(request, response);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    }
    

    TestControllerServlet

    在同一个包还可以创建其他类似的类

    import java.io.IOException;
    
    public class TestControllerServlet implements Servlet{
    
    	@Override
    	public void init() {
    	}
    
    
    	@Override
    	public void destroy() {
    	}
    
    	@Override
    	public void service(Request request, Response response) {
    		String message = "HTTP/1.1 200 ok\r\n\r\nhello";
    		try {
    			response.out.write(message.getBytes());
    			response.out.flush();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    }
    

    请求测试

    http://localhost:8080/servlet/TestControllerServlet

  • 相关阅读:
    Redis实战 - 15 Redis事务机制和乐观锁实现
    aqistudy真气网JS逆向 + 数据采集(20220801)
    三款经典的轮式/轮足机器人讲解,以及学习EG2133产生A/B/C驱动电机。个人机器人学习和开发路线(推荐)
    uni-number-box的坑-无法实现数据双向绑定
    安装JoySSL的SSL证书有什么优势?
    springcloud gateway网关浅析
    SwiftUI AI之如何使用 DALL-E API——生成人脸(教程含源码)
    【杂七杂八】Windows和Linux怎么配置环境变量
    跨境电商测评内幕及自养号技术教学
    java多个jar包编译生成.class文件
  • 原文地址:https://blog.csdn.net/Myueye/article/details/127110554