ケース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アプレットの実行のサービス側もの!