Tomcat--が行われ、手動TOMCAT2

ケース1.需要

クライアントがサーバに要求を送信すると、サーバーはクライアントへのJavaコードの期間を実行し、応答データすることができます

2.コードの実装

プロジェクトのディレクトリ構造図

2.1定義するインターフェイスサーブレット

インタフェースは従わなければならないすべてのサーバーのインタフェースを実行するためのJavaアプレットです

package cn.bjc.mytomcat.v2;

import java.io.InputStream;
import java.io.OutputStream;

public interface Servlet {
	public void init();
	public void service(InputStream in,OutputStream out);
	public void destroy();
}

2.2サーバ側のJavaアプレットやサーブレットAServletを実装

AServlet

package cn.bjc.mytomcat.v2;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class AServlet implements Servlet {

	@Override
	public void init() {
		System.out.println("A Servlet init...");
	}

	@Override
	public void service(InputStream in, OutputStream out) {
		System.out.println("A Servlet service");
		try {
			out.write("from A Servlet!".getBytes());
			out.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void destroy() {
		System.out.println("A Servlet Destroy");
	}

}

BServlet

package cn.bjc.mytomcat.v2;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class BServlet implements Servlet {

	@Override
	public void init() {
		System.out.println("B Servlet init...");
	}

	@Override
	public void service(InputStream in, OutputStream out) {
		System.out.println("B Servlet service");
		try {
			out.write("from B Servlet!".getBytes());
			out.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void destroy() {
		System.out.println("B Servlet Destroy");
	}

}

サーバー側のアプレットの2.3構成パラメータ

config.properties

aa=cn.bjc.mytomcat.v2.AServlet
bb=cn.bjc.mytomcat.v2.BServlet

勉強を開始する2.4サーバーの設定パラメータ

TESTSERVER構成情報は地図、ストレージサーバのconfig.propertiesの静的な型を定義します

// 定义一个静态类型的Map,存储服务端config.properties中的配置信息
private static Map<String,String> map = new HashMap<String,String>();
// 服务端启动之前将配置参数中的信息加载到Map
static {
	// 1. 创建一个Properties对象
	Properties pro = new Properties();
	try {
		// 2. 加载WebContent目录下的config.properties文件
		pro.load(new FileInputStream(WEB_ROOT+"\\config.properties"));
		// 3. 将配置文件中的数据读取到Map
		Set keys = pro.keySet();
		Iterator iterator = keys.iterator();
		while(iterator.hasNext()){
			String key = (String) iterator.next();
			String value = pro.getProperty(key);
			map.put(key, value);
		}
	} catch (Exception e) {
		e.printStackTrace();
	}	
}

2.5送信ダイナミックリソース

// 发送动态资源
private static void sendDynamicResource(InputStream in,OutputStream out) throws Exception{
	// 1. 判断HTTP协议的响应行和响应头发送到客户端
	out.write("HTTP/1.1 200 OK\n".getBytes());
	out.write("Server:apache-Coyote/1.1\n".getBytes());
	out.write("Content-Type:text/html;charset=utf-8\n".getBytes());
	out.write("\n".getBytes());
	// 2. 判断map中是否存在一个key,这个key是否与本次请求的资源路径一致
	if(map.containsKey(url)){
		// 3. 如果包含指定的key,获取到Map中的key对应的value
		String value = map.get(url);
		// 4. 通过反射,将对应的java程序加载到内存
		Class clazz = Class.forName(value);
		Servlet servlet = (Servlet)clazz.newInstance();
		// 5. 执行init
		servlet.init();
		// 6. 执行service方法
		servlet.service(in, out);	
	} else {
		String errMsg = "no mapping for " + url;
		out.write(errMsg.getBytes());
	}
}

実行します。

 

完全なコードTESTSERVER

package cn.bjc.mytomcat.v2;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class TestServer {

	// 定义静态变量,用于存放服务端weContent目录的绝对路径
	public static String WEB_ROOT = System.getProperty("user.dir")+File.separator+"webContent";
	// 定义静态变量,用于存放本次请求的静态页面的名称
	private static String url;
	
	// 定义一个静态类型的Map,存储服务端config.properties中的配置信息
	private static Map<String,String> map = new HashMap<String,String>();
	// 服务端启动之前将配置参数中的信息加载到Map
	static {
		// 1. 创建一个Properties对象
		Properties pro = new Properties();
		try {
			// 2. 加载WebContent目录下的config.properties文件
			pro.load(new FileInputStream(WEB_ROOT+"\\config.properties"));
			// 3. 将配置文件中的数据读取到Map
			Set keys = pro.keySet();
			Iterator iterator = keys.iterator();
			while(iterator.hasNext()){
				String key = (String) iterator.next();
				String value = pro.getProperty(key);
				map.put(key, value);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	public static void main(String[] args) throws Exception {
		ServerSocket server = null;
		Socket socket = null;
		OutputStream out = null;
		InputStream in = null;
		// 1. 创建ServerSocket,监听本地8080端口,等待来自客户端的请求
		try {
			server = new ServerSocket(8080);
			while(true){
				// 获取客户端对应的socket
				socket = server.accept();
				// 获取输入流对象
				in = socket.getInputStream();
				// 获取输出流对象
				out = socket.getOutputStream();
				// 获取HTTP协议的请求部分,截取客户端要访问的资源名称,将这个资源名称赋值给url
				parse(in);
				// 根据url判断请求的是静态还是动态的
				if(null != url){
					if(url.indexOf(".") != -1){
						// 发送静态资源
						sendStaticResource(out);
					} else {
						sendDynamicResource(in, out);
					}
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			
		}
	}
	
	// 发送动态资源
	private static void sendDynamicResource(InputStream in,OutputStream out) throws Exception{
		// 1. 判断HTTP协议的响应行和响应头发送到客户端
		out.write("HTTP/1.1 200 OK\n".getBytes());
		out.write("Server:apache-Coyote/1.1\n".getBytes());
		out.write("Content-Type:text/html;charset=utf-8\n".getBytes());
		out.write("\n".getBytes());
		// 2. 判断map中是否存在一个key,这个key是否与本次请求的资源路径一致
		if(map.containsKey(url)){
			// 3. 如果包含指定的key,获取到Map中的key对应的value
			String value = map.get(url);
			// 4. 通过反射,将对应的java程序加载到内存
			Class clazz = Class.forName(value);
			Servlet servlet = (Servlet)clazz.newInstance();
			// 5. 执行init
			servlet.init();
			// 6. 执行service方法
			servlet.service(in, out);
			
		} else {
			String errMsg = "no mapping for " + url;
			out.write(errMsg.getBytes());
		}
	}
	
	// 发送静态资源
	private static void sendStaticResource(OutputStream out) throws Exception {
		// 1. 定义一个字节数组,用于存放本次请求的静态资源demo01.html的内容
		byte[] bytes = new byte[2048];
		// 2. 定义一个文件输入流,用户获取静态资源demo01.html中的内容
		FileInputStream fis = null;
		try {
			// 3. 创建文件对象File,代表本次要请求的资源demo01.html
			File file = new File(WEB_ROOT,url);
			// 4. 如果文件存在
			if(file.exists()){
				// 4.1 向客户端输出HTTP协议的响应行/响应头
				out.write("HTTP/1.1 200 OK\n".getBytes());
				out.write("Server:apache-Coyote/1.1\n".getBytes());
				out.write("Content-Type:text/html;charset=utf-8\n".getBytes());
				out.write("\n".getBytes());
				// 4.2 获取到文件输入流对象
				fis = new FileInputStream(file);
				// 4.3 读取静态资源demo01.html中的内容到数组中
				int ch = fis.read(bytes);
				while(ch != -1){
					// 4.4 将读取到数组中的内容通过输出流发送到客户端
					out.write(bytes, 0, ch);
					ch = fis.read(bytes);
				}
			}else {
				// 5. 如果文件不存在
				// 5.1 向客户端响应文件不存在的消息
				out.write("HTTP/1.1 404 not found\n".getBytes());
				out.write("Server:apache-Coyote/1.1\n".getBytes());
				out.write("Content-Type:text/html;charset=utf-8\n".getBytes());
				out.write("\n".getBytes());
				String errMsg = "file not found";
				out.write(errMsg.getBytes());
			}
		} catch(Exception e){
			e.printStackTrace();
		}finally {
			// 6. 释放资源
			if(null != fis){
				fis.close();
			}
		}
		
	}
	private static void parse(InputStream in) throws Exception {
		// 1. 定义一个变量,存放HTTP协议请求部分数据
		StringBuffer content = new StringBuffer();
		// 2. 定义一个数组,存放HTTP协议请求部分数据
		byte[] buffer = new byte[2048];
		// 3. 定义一个变量i,代表读取数据到数组中之后,数据量的大小
		int i = -1;
		// 4. 读取客户端发过来的数据,将数据读取到字节数组buffer中,i代表读取数据量的大小311字节
		i = in.read(buffer);
		// 5. 遍历字节数组,将数组中的数据追加到content变量中
		for(int j = 0 ; j < i ; j++){
			content.append((char)buffer[j]);
		}
		// 6. 打印HTTP协议请求部分数据
		System.out.println(content);
		// 7. 截取客户端要请求的资源路径 demo.html,赋值给url
		parseUrl(content.toString());
		System.out.println(url);
	}

	// 解析请求数据得到请求连接
	private static void parseUrl(String content) {
		/*
		 * 	GET /erp/dep/getAll HTTP/1.1
			Host: localhost:8080
			Connection: keep-alive
			Upgrade-Insecure-Requests: 1
			User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
			Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng;q=0.8
			Accept-Encoding: gzip, deflate, br
			Accept-Language: zh-CN,zh;q=0.9
			Cookie: __guid=111872281.1743065663273879000.1567260921404.8972
		 * 
		 * */
		// 1. 截取客户端请求资源的名称   /erp/dep/getAll
		// 2. 定义2个变量,存放请求行的2个空格位置
		int index1,index2;
		// 3. 获取http请求行的第一个空格的位置
		index1 = content.indexOf(" ");
		if(index1 != -1){ // 表示存在第一个空格
			// 从第一个空格之后开始查找
			// 4. 获取http请求行的第二个空格的位置
			index2 = content.indexOf(" ", index1+1);
			if(index2 > index1){
				// 5. 截取字符串获取到本次请求的资源的名称
				url = content.substring(index1+2, index2);
			}
		}
	}

}

要約:

        手動でTomcatを実装することで、我々はまだ、サーバサイドJavaプログラムの性質上で実行されているJavaアプレットを見つけることができますが、我々は合意されたサーブレットにこのインタフェースを実装する必要がある、あなただけの、その後我々は、ブラウザを介しすることができ、対応する設定情報を行う必要がありますサーバーは、要求を送信し、そのJavaアプレットの実行のサービス側もの!

公開された128元の記事 ウォンの賞賛6 ビュー3231

おすすめ

転載: blog.csdn.net/weixin_43318134/article/details/103749160
おすすめ