java實現自定義服務器

自定義服務器整個項目結構
在這裏插入圖片描述

  1. 自定義請求類MyHttpServletRequest,處理請求
package com.myserver;

import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

/**
 * 自定義請求類,處理請求
 * @author fang
 *
 */
public class MyHttpServletRequest {

	/**
	 * 請求的動作
	 */
	private String action;

	/**
	 * 存放請求的參數
	 */
	private Map<String, String> paramMap = new HashMap<String, String>();

	public MyHttpServletRequest() {
	}

	public MyHttpServletRequest(InputStream is) throws IOException {

		// 創建一個用來接收的數據盒子
		byte[] buf = new byte[1024];
		// 接收並返回長度
		int len = is.read(buf);
		if (len == 0) {
			return;
		}
		// 取得請求數據,進行解碼,防止中文亂碼
		String data = new String(buf, 0, len);
		data = URLDecoder.decode(data, "utf-8");
		// 處理GET請求
		if (data.startsWith("GET")) {
			// 判斷是否帶參數
			if (data.contains("?")) {
				// 取得參數的字符串
				String params = data.substring(data.indexOf("?") + 1, data.indexOf("HTTP/1.1") - 1);
				// 取得帶參數的請求動作
				this.action = data.substring(data.indexOf("/"), data.indexOf("?"));
				// 解析取得請求動作,將取得請求的參數存放到HashMap中
				if (params != null && !"".equals(params)) {
					parseParams(params);
				}
			} else {
				this.action = data.substring(data.indexOf("/"), data.indexOf("HTTP") - 1);
			}

		}
		// 處理PSOT請求
		if (data.startsWith("POST")) {
			int start = data.indexOf("POST") + 6;
			int end = data.indexOf("HTTP/1.1") - 1;

			// 取得請求動作
			this.action = data.substring(start, end);

			// 最後一個換行符
			int beginIndex = data.lastIndexOf("\n") + 1;
			// 取得請求參數的字符串
			String params = data.substring(beginIndex);
			// 解析參數
			if (params != null && !"".equals(params)) {
				parseParams(params);
			}
		}

	}

	/**
	 * 解析參數,將取得請求的參數存放到HashMap中
	 * 
	 * @param params 參數字符串
	 * @return 請求動作
	 */
	private void parseParams(String params) {

		// 解析參數字符串
		if (params.contains("&")) {
			// 多個參數以&爲分割符
			String[] temp = params.split("&");
			if (temp != null) {
				for (int i = 0; i < temp.length; i++) {
					// key=value的形式
					String[] t = temp[i].split("=");
					// 存入集合
					paramMap.put(t[0], t[1]);
				}
			}
		} else {
			String[] p = params.split("=");
			// 存入集合
			paramMap.put(p[0], p[1]);
		}
	}

	/**
	 * 取得請求的動作
	 * 
	 * @return action
	 */
	public String getAction() {
		return action;
	}

	/**
	 * 取得屬性值
	 * 
	 * @param key 鍵值
	 * @return 屬性值
	 */
	public String getAttributeValue(String key) {
		if (paramMap.size() <= 0) {
			return null;
		}
		return paramMap.get(key);
	}

	/**
	 * 設置屬性
	 * 
	 * @param key   鍵值
	 * @param value 屬性值
	 */
	public void setAttribute(String key, String value) {
		paramMap.put(key, value);
	}

	/**
	 * 移除屬性
	 * 
	 * @param key 屬性對應的鍵值
	 */
	public void removeAttribute(String key) {
		paramMap.remove(key);
	}

}

  1. 自定義響應類MyHttpServletResponse,響應請求
package com.myserver;

import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

/**
 * 自定義請求類,處理請求
 * @author fang
 *
 */
public class MyHttpServletRequest {

	/**
	 * 請求的動作
	 */
	private String action;

	/**
	 * 存放請求的參數
	 */
	private Map<String, String> paramMap = new HashMap<String, String>();

	public MyHttpServletRequest() {
	}

	public MyHttpServletRequest(InputStream is) throws IOException {

		// 創建一個用來接收的數據盒子
		byte[] buf = new byte[1024];
		// 接收並返回長度
		int len = is.read(buf);
		if (len == 0) {
			return;
		}
		// 取得請求數據,進行解碼,防止中文亂碼
		String data = new String(buf, 0, len);
		data = URLDecoder.decode(data, "utf-8");
		// 處理GET請求
		if (data.startsWith("GET")) {
			// 判斷是否帶參數
			if (data.contains("?")) {
				// 取得參數的字符串
				String params = data.substring(data.indexOf("?") + 1, data.indexOf("HTTP/1.1") - 1);
				// 取得帶參數的請求動作
				this.action = data.substring(data.indexOf("/"), data.indexOf("?"));
				// 解析取得請求動作,將取得請求的參數存放到HashMap中
				if (params != null && !"".equals(params)) {
					parseParams(params);
				}
			} else {
				this.action = data.substring(data.indexOf("/"), data.indexOf("HTTP") - 1);
			}

		}
		// 處理PSOT請求
		if (data.startsWith("POST")) {
			int start = data.indexOf("POST") + 6;
			int end = data.indexOf("HTTP/1.1") - 1;

			// 取得請求動作
			this.action = data.substring(start, end);

			// 最後一個換行符
			int beginIndex = data.lastIndexOf("\n") + 1;
			// 取得請求參數的字符串
			String params = data.substring(beginIndex);
			// 解析參數
			if (params != null && !"".equals(params)) {
				parseParams(params);
			}
		}

	}

	/**
	 * 解析參數,將取得請求的參數存放到HashMap中
	 * 
	 * @param params 參數字符串
	 * @return 請求動作
	 */
	private void parseParams(String params) {

		// 解析參數字符串
		if (params.contains("&")) {
			// 多個參數以&爲分割符
			String[] temp = params.split("&");
			if (temp != null) {
				for (int i = 0; i < temp.length; i++) {
					// key=value的形式
					String[] t = temp[i].split("=");
					// 存入集合
					paramMap.put(t[0], t[1]);
				}
			}
		} else {
			String[] p = params.split("=");
			// 存入集合
			paramMap.put(p[0], p[1]);
		}
	}

	/**
	 * 取得請求的動作
	 * 
	 * @return action
	 */
	public String getAction() {
		return action;
	}

	/**
	 * 取得屬性值
	 * 
	 * @param key 鍵值
	 * @return 屬性值
	 */
	public String getAttributeValue(String key) {
		if (paramMap.size() <= 0) {
			return null;
		}
		return paramMap.get(key);
	}

	/**
	 * 設置屬性
	 * 
	 * @param key   鍵值
	 * @param value 屬性值
	 */
	public void setAttribute(String key, String value) {
		paramMap.put(key, value);
	}

	/**
	 * 移除屬性
	 * 
	 * @param key 屬性對應的鍵值
	 */
	public void removeAttribute(String key) {
		paramMap.remove(key);
	}

}
  1. 定義處理請求線程類ProcessedThread
package com.myserver;

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.Socket;

import com.servlet.LoginServlet;

/**
 * 定義處理請求線程類
 * 
 * @author fang
 *
 */
public class ProcessedThread implements Runnable {
	
	/**
	 * 客戶端套接字
	 */
	private Socket socket = null;
	
	public ProcessedThread(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		InputStream is = null;
		OutputStream os = null;
		try {
			is = socket.getInputStream();
			if (is == null) {
				throw new NullPointerException();
			}
			os = socket.getOutputStream();
			if (os == null) {
				throw new NullPointerException();
			}
			// 創建響應對象實例
			MyHttpServletResponse response = new MyHttpServletResponse(os);
			// 創建請求對象
			MyHttpServletRequest request = new MyHttpServletRequest(is);
			// 取得請求動作
			String action = request.getAction();
			String filePath = null;
			if (action == null || "".equals(action)) {
				response.forward("404.html");
				return;
			}
			boolean result = isSuffix(action);
			// 處理靜態業務類
			if (result) {
				filePath = "webContent" + request.getAction();
				File file = new File(filePath);
				if (!file.exists()) {
					response.forward("404.html");
					return;
				}
				response.write(new FileInputStream(filePath));

			}
			// 處理動態業務類
			if (!result) {
				if (action.endsWith("login.do")) {
					LoginServlet loginServlet = new LoginServlet();
					loginServlet.doService(request, response);
				}
			}

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				os.close();
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	//靜態業務 允許請求的後綴
	String[] suffixs = { ".html", ".js", ".css", ".jpg", ".ico" };

	public boolean isSuffix(String action) {
		boolean isAllow = false;
		// 判斷是否有
		for (String suffix : suffixs) {
			if (action.endsWith(suffix)) {
				isAllow = true;
				break;
			}
		}
		return isAllow;
	}

}

  1. 實現自定義服務器類MyServer
package com.myserver;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 實現自定義服務器
 * @author fang
 *
 */
public class MyServer {
	/**
	 * 服務端套接字
	 */
	private ServerSocket serverSocket=null;
	/**
	 * 客戶端套接字
	 */
	private Socket socket=null;
	
	/**
	 * 初始化服務器
	 * @param port 端口號 默認80
	 * @throws IOException
	 */
	public MyServer(int port) throws IOException {
		//開啓服務端
		serverSocket=new ServerSocket(port);
		System.out.println("服務器開啓成功");
		while(true) {
			//等待客戶端連接
			socket=serverSocket.accept();
			//創建處理請求的線程
			ProcessedThread processedThread=new ProcessedThread(socket);
			//使用定長線程池
			ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
			//開始執行
			fixedThreadPool.execute(processedThread);
		}
	}
	public Socket getSocket() {
		return socket;
	}
	
	public static void main(String[] args) throws IOException {
		new MyServer(80);
	}

}
  1. 測試登錄類
package com.servlet;

import java.io.FileNotFoundException;
import java.io.IOException;

import com.myserver.MyHttpServletRequest;
import com.myserver.MyHttpServletResponse;

/**
 * 測試登錄
 * @author fang
 *
 */
public class LoginServlet {
	
	public void doService(MyHttpServletRequest request,MyHttpServletResponse response) throws FileNotFoundException, IOException{
		//取得帳號和密碼
		String userName=request.getAttributeValue("userName");
		String password=request.getAttributeValue("password");
		if ("fangzi".equals(userName) && "666".equals(password)) {
			response.forward("/main.html");
		}else {
			response.forward("/failed.html");
		}
	}

}

前端頁面
首頁index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>歡迎界面</title>
</head>
<body>
	<h1>歡迎使用自定義服務器</h1>
</body>
</html>

登錄界面login.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登錄</title>
</head>
<body>
	<h1>登錄界面</h1>
	<form action="login.do" method="post">
		<p>
			賬號:<input name="userName" />
		</p>
		<p>
			密碼:<input name="password" />
		</p>

		<p>
			<button>登錄</button>
		</p>
	</form>

</body>
</html>

登錄成功main.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>首頁</title>
</head>
<body>
	登錄成功
</body>
</html>

登錄失敗failed.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登錄失敗</title>
</head>
<body>
	<h1>賬號或密碼錯誤</h1>
	<hr>
	<p>
		<a href="login.html">返回</a>
	</p>
</body>
</html>

圖標文件favicon.ico
注意:圖標這個文件一定要有,可以新建一個文件後綴名設置爲.ico

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章