1. package controller;
    2. import server.HttpServletRequest;
    3. import server.HttpServletResponse;
    4. public class IndexController {
    5. public void test(HttpServletRequest hsr, HttpServletResponse response){
    6. //传入的参数也是用于携带返回的信息的参数,例如之前学到的流,传入数组,返回值也在数组里
    7. //1.获取请求发送过来携带的参数(可能没有)
    8. System.out.println("控制层工作了");
    9. //2.找到某一个业务层做事
    10. //3.将最终业务层执行完毕的结果交还给服务器,服务器再将结果返回浏览器
    11. }
    12. }
    1. package server;
    2. import java.util.HashMap;
    3. public class HttpServletRequest {//为了存储浏览器发送请求时携带的所有信息
    4. private String content;
    5. private HashMap<String,String>map=new HashMap<>();
    6. public HttpServletRequest() {
    7. }
    8. public HttpServletRequest(String content, HashMap<String, String> map) {
    9. this.content = content;
    10. this.map = map;
    11. }
    12. public String getContent() {
    13. return content;
    14. }
    15. public HashMap<String, String> getMap() {
    16. return map;
    17. }
    18. public void setContent(String content) {
    19. this.content = content;
    20. }
    21. public void setMap(HashMap<String, String> map) {
    22. this.map = map;
    23. }
    24. }
    1. package server;
    2. public class HttpServletResponse {//用于接收响应回来的结果
    3. }
    1. package server;
    2. import java.net.ServerSocket;
    3. import java.net.Socket;
    4. public class Server {
    5. public void startServer(){
    6. try {
    7. System.out.println("====启动服务====");
    8. //自己创建服务
    9. ServerSocket server=new ServerSocket(9999);
    10. while (true){
    11. //等待某一个客户端过来连接
    12. Socket socket=server.accept();//要想同时很多用户访问,可以用多线程来控制
    13. new ServerHandler(socket).start();
    14. }
    15. }catch (Exception e){
    16. e.printStackTrace();
    17. }
    18. }
    19. }
    package server;
    
    import controller.IndexController;
    
    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.lang.reflect.Method;
    import java.net.Socket;
    import java.util.HashMap;
    import java.util.Properties;
    
    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 br = new BufferedReader(isr);//包装成高级流,可以读取一行
                //读取消息  资源名?key=value&key=value
                String contentAndParams = br.readLine();
                //调用一个方法解析读取过来的信息
                this.parseContentAndParams(contentAndParams);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        private void parseContentAndParams(String contentAndParams) {//解析
            //资源名?key=value&key=value
            HashMap<String, String> map = new HashMap<>();
            String content = null;
            int questionMarkIndex = contentAndParams.indexOf("?");
            if (questionMarkIndex != -1) {
                content = contentAndParams.substring(0, questionMarkIndex);
                String params = contentAndParams.substring(contentAndParams.indexOf("?") + 1);
                String[] kv = params.split("&");
    
                for (String str : kv) {
                    String[] values = str.split("=");
                    map.put(values[0], values[1]);
                }
            } else {
                //没有携带参数,请求发过来的信息就是完整的资源名
                content = contentAndParams;
            }
            //自己创建两个对象,一个用于包含所有携带的信息,一个用于接收响应回来的结果
            HttpServletRequest hsr=new HttpServletRequest(content,map);
            HttpServletResponse response=new HttpServletResponse();//空的
            this.findController(hsr,response);
        }
    
        private void findController(HttpServletRequest hsr,HttpServletResponse response) {//找人做事---控制层
            try {
                //获取request对象中的请求名字(简单名,我们在内存中已经将简单名与类全名对应存好)
                String content=hsr.getContent();
                //参考配置文件
                Properties properties=new Properties();
                properties.load(new FileReader("src//web.properties"));
                String realControllerName=properties.getProperty(content);
                //反射获取类
                Class clazz=Class.forName(realControllerName);
                Object obj=clazz.newInstance();
                Method method= clazz.getMethod("test",HttpServletRequest.class,HttpServletResponse.class);
                method.invoke(obj,hsr,response);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    
        private void responseToBrowser() {//将最终响应信息写回浏览器
    
        }
    
    }
    
    package test;
    
    import server.Server;
    
    public class TestMain {
        public static void main(String[] args){
            new Server().startServer();
        }
    }
    

    image.png
    ========================================================================

    package browser;
    
    import java.io.PrintWriter;
    import java.net.Socket;
    import java.util.Scanner;
    
    public class Browser {
        private Scanner input=new Scanner(System.in);
    
        public void openBrowser(){//模拟打开浏览器
            //输入一个URL统一资源定位符    ip:port/资源名?key=value&key=value
            System.out.println("URL:");
            String url=input.nextLine();
            this.parseURL(url);
        }
    
        private void parseURL(String url){//解析URL,拆成三段
            int colonIndex=url.indexOf(":");
            int slashIndex=url.indexOf("/");
            String ip=url.substring(0,colonIndex);//获取ip地址
            int port=Integer.parseInt(url.substring(colonIndex+1,slashIndex));//获取port
            String contentAndParams=url.substring(slashIndex+1);
            this.createSocketAndSendRequest(ip,port,contentAndParams);
        }
    
        //创建一个socket,将contentAndParams发送给服务器
        private void createSocketAndSendRequest(String ip,int port,String contentAndParams){
            try {
                //通过ip和port创建一个socket
                Socket socket=new Socket(ip,port);
                //将contentAndParams发送出去(给服务器)
                PrintWriter out=new PrintWriter(socket.getOutputStream());//需要一个高级流来发送
                out.println(contentAndParams);
                out.flush();
                //浏览器等待响应消息
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    
    }
    
    package test;
    
    import browser.Browser;
    
    public class TestMain {
        public static void main(String[] args){
            new Browser().openBrowser();
        }
    }
    

    QQ录屏20210310181348.mp4 (10.43MB)