1、请求响应原理图
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/5c6d4c1b6f4428388f49e0f6c5352044.png)
2、浏览器端示例代码
2.1浏览器类
package browser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Scanner;
public class Browser1 {
private Scanner input = new Scanner(System.in);
private Socket socket;
private String ip;
private int port;
public void openBrowser(){
System.out.print("URL:");
String url = input.nextLine();
this.parseURL(url);
}
private void parseURL(String url){
int colonIndex = url.indexOf(":");
int slashIndex = url.indexOf("/");
ip = url.substring(0,colonIndex);
port = Integer.parseInt(url.substring(colonIndex+1,slashIndex));
String contentAndParams = url.substring(slashIndex+1);
this.createSocketAndSendRequest(ip,port,contentAndParams);
}
private void createSocketAndSendRequest(String ip,int port,String contentAndParams){
try {
socket = new Socket(ip,port);
PrintWriter out = new PrintWriter(socket.getOutputStream());
out.println(contentAndParams);
out.flush();
this.receiveResponseContent();
} catch (IOException e) {
e.printStackTrace();
}
}
private void receiveResponseContent(){
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String responseContent = reader.readLine();
this.parseResponseContentAndShow(responseContent);
} catch (IOException e) {
e.printStackTrace();
}
}
private void parseResponseContentAndShow(String responseContent){
String content = null;
HashMap<String,String> paramsMap = null;
responseContent = responseContent.replace("<br>","\r\n");
while(true){
int lessThanIndex = responseContent.indexOf("<");
int greaterThenIndex = responseContent.indexOf(">");
if(lessThanIndex!=-1 && greaterThenIndex!=-1 && lessThanIndex<greaterThenIndex){
System.out.println(responseContent.substring(0,lessThanIndex));
String tag = responseContent.substring(lessThanIndex,greaterThenIndex+1);
if(tag.contains("input")){
String value = input.nextLine();
if(paramsMap==null){
paramsMap = new HashMap<String,String>();
}
String[] keyAndValues = tag.split(" ");
for(String keyAndValue : keyAndValues){
if(keyAndValue.contains("=")){
String[] KV = keyAndValue.split("=");
if("name".equals(KV[0])){
paramsMap.put(KV[1].substring(1,KV[1].length()-1),value);
}
}
}
}else if(tag.contains("form")){
String[] keyAndValues = tag.split(" ");
for(String keyAndValue : keyAndValues){
if(keyAndValue.contains("=")){
String[] KV = keyAndValue.split("=");
if("action".equals(KV[0])){
content = KV[1].substring(1,KV[1].length()-1);
}
}
}
}
responseContent = responseContent.substring(greaterThenIndex+1);
}else{
System.out.print(responseContent);
break;
}
}
this.sendNewRequest(content,paramsMap);
}
private void sendNewRequest(String content,HashMap<String,String> paramsMap){
if(content!=null){
StringBuilder url = new StringBuilder(ip);
url.append(":");
url.append(port);
url.append("/");
url.append(content);
if(paramsMap!=null){
url.append("?");
Iterator<String> it = paramsMap.keySet().iterator();
while(it.hasNext()){
String key = it.next();
String value = paramsMap.get(key);
url.append(key);
url.append("=");
url.append(value);
url.append("&");
}
url.delete(url.length()-1,url.length());
}
this.parseURL(url.toString());
}
}
}
2.2主启动类
package test;
import browser.Browser;
import browser.Browser1;
public class TestMain {
public static void main(String[] args){
new Browser1().openBrowser();
}
}
3、服务器端示例代码
3.1、服务器核心类
package servers;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public void startServer(){
try {
System.out.println("====启动服务器====");
int port = Integer.parseInt(ServerFileReader.getValue("port"));
ServerSocket server = new ServerSocket(port);
while(true){
Socket socket = server.accept();
new ServerHandler(socket).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.2、ServerFileReader读取配置类
package servers;
import java.io.FileReader;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Properties;
public class ServerFileReader {
private static HashMap<String,String> map = new HashMap<String,String>();
static{
try {
Properties pro = new Properties();
pro.load(new FileReader("src/server.properties"));
Enumeration en = pro.propertyNames();
while(en.hasMoreElements()){
String key = (String)en.nextElement();
String value = pro.getProperty(key);
map.put(key,value);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static String getValue(String key){
return map.get(key);
}
}
3.3、server.properties配置文件
port=9999
3.4、ServerHandler创建线程负责处理当前浏览器发送过来的消息
package servers;
import java.io.*;
import java.net.Socket;
import java.util.HashMap;
public class ServerHandler extends Thread {
private Socket socket;
public ServerHandler(Socket socket){
this.socket = socket;
}
public void run(){
this.receiveRequest();
}
private void receiveRequest(){
try {
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader reader = new BufferedReader(isr);
String contentAndParams = reader.readLine();
this.parseContentAndParams(contentAndParams);
} catch (IOException e) {
e.printStackTrace();
}
}
private void parseContentAndParams(String contentAndParams){
String content = null;
HashMap<String,String> paramsMap = null;
int questionMarkIndex = contentAndParams.indexOf("?");
if(questionMarkIndex!=-1){
content = contentAndParams.substring(0,questionMarkIndex);
paramsMap = new HashMap<String,String>();
String params = contentAndParams.substring(questionMarkIndex+1);
String[] keyAndValues = params.split("&");
for(String keyAndValue : keyAndValues){
String[] KV = keyAndValue.split("=");
paramsMap.put(KV[0],KV[1]);
}
}else{
content = contentAndParams;
}
HttpServletRequest request = new HttpServletRequest(content,paramsMap);
HttpServletResponse response = new HttpServletResponse();
ServletController.findController(request,response);
this.responseToBrowser(response);
}
private void responseToBrowser(HttpServletResponse response){
try {
PrintWriter out = new PrintWriter(socket.getOutputStream());
out.println(response.getResponseContent());
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.5、HttpServletRequest(存储浏览器发送请求时携带的所有信息)
package servers;
import java.util.HashMap;
public class HttpServletRequest {
private String content;
private HashMap<String,String> paramsMap;
public HttpServletRequest() {}
public HttpServletRequest(String content, HashMap<String, String> paramsMap) {
this.content = content;
this.paramsMap = paramsMap;
}
public String getParameter(String key){
return this.paramsMap.get(key);
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public void setParamsMap(HashMap<String, String> paramsMap) {
this.paramsMap = paramsMap;
}
}
3.6、HttpServletResponse(存储响应信息)
package servers;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
public class HttpServletResponse {
private StringBuilder responseContent = new StringBuilder();
public void write(String str){
this.responseContent.append(str);
}
public void sendRedirect(String path){
try {
File file = new File("src//file//"+path);
BufferedReader reader = new BufferedReader(new FileReader(file));
String value = reader.readLine();
while(value!=null){
this.responseContent.append(value);
value = reader.readLine();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public String getResponseContent(){
return this.responseContent.toString();
}
}
3.7、读取响应信息为:
****************<br>
****银行系统****<br>
****************<br>
<form action="login" method="">
请输入账号<input name="name" value=""><br>
请输入密码<input name="password" value=""><br>
3.8 、定义统一规则
package servers;
public abstract class HttpServlet {
public abstract void service(HttpServletRequest request, HttpServletResponse response);
}
3.9 主界面控制层
package controller;
import servers.HttpServlet;
import servers.HttpServletRequest;
import servers.HttpServletResponse;
public class IndexController extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response){
response.sendRedirect("index.view");
}
}
4.0.登录控制层
package controller;
import servers.HttpServlet;
import servers.HttpServletRequest;
import servers.HttpServletResponse;
public class LoginController extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response) {
String name = request.getParameter("name");
String password = request.getParameter("password");
System.out.println(name+"---"+password);
}
}
4.1、ServletController (参考web.properties文件读取具体Controller并提供缓存)
package server;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Properties;
public class ServletController {
private static HashMap<String,String> controllerNameMap = new HashMap<>();
private static HashMap<String,HttpServlet> controllerObjectMap = new HashMap<>();
static{
try {
Properties pro = new Properties();
pro.load(new FileReader("src//web.properties"));
Enumeration en = pro.propertyNames();
while(en.hasMoreElements()){
String content = (String)en.nextElement();
String realControllerName = pro.getProperty(content);
controllerNameMap.put(content,realControllerName);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void findController(HttpServletRequest request,HttpServletResponse response){
String content = request.getContent();
try {
HttpServlet controllerObject = controllerObjectMap.get(content);
if(controllerObject==null){
String realControllerName = controllerNameMap.get(content);
if(realControllerName!=null){
Class clazz = Class.forName(realControllerName);
controllerObject = (HttpServlet) clazz.newInstance();
controllerObjectMap.put(content,controllerObject);
}
}
Class controllerClass = controllerObject.getClass();
Method serviceMethod = controllerClass.getMethod("service",HttpServletRequest.class,HttpServletResponse.class);
serviceMethod.invoke(controllerObject,request,response);
} catch (ClassNotFoundException e) {
response.write("请求的"+content+"Controller不存在");
} catch (NoSuchMethodException e){
response.write("405 没有可以执行的方法");
} catch (Exception e){
e.printStackTrace();
}
}
}
4.2、web.properties配置文件如下
index=controller.IndexController
login=controller.LoginController