栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JSD-2204-WebServer(项目终章)-Day18

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JSD-2204-WebServer(项目终章)-Day18

1.V25(版本)
利用反射机制重构DispatcherServlet,使得将来添加新的业务时DispatcherServlet
不必再添加分支判断(不进行修改)

实现:
1:新建包com.webserver.annotation
2:在annotation包下添加两个注解
  @Controller:用于标注哪些类是处理业务的Controller类
  @RequestMapping:用于标注处理某个业务请求的业务方法
3:将com.webserver.controller包下的所有Controller类添加注解@Controller
  并将里面用于处理某个业务的方法标注@RequestMapping并指定该方法处理的请求
4:DispatcherServlet在处理请求时,先扫描controller包下的所有Controller类
  并找到处理该请求的业务方法,使用反射调用.
1.1项目目录

1.2Java文件  1.2.1Controller(注解)
package com.webserver.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Controller {
}
1.2.2RequestMapping(注解)
package com.webserver.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestMapping {
    String value();
}
1.2.3ClientHandler
package com.webserver.core;

import com.webserver.http.EmptyRequestException;
import com.webserver.http.HttpServletRequest;
import com.webserver.http.HttpServletResponse;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.net.Socket;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;


public class ClientHandler implements Runnable{
    private Socket socket;
    public ClientHandler(Socket socket){
        this.socket = socket;
    }

    public void run() {
        try {
            //1解析请求
            HttpServletRequest request = new HttpServletRequest(socket);
            HttpServletResponse response = new HttpServletResponse(socket);

            //2处理请求
            DispatcherServlet servlet = new DispatcherServlet();
            servlet.service(request,response);

            //3发送响应
            response.response();



        } catch (IOException e) {
            e.printStackTrace();
        } catch (EmptyRequestException e) {

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } finally {
            try {
                //按照HTTP协议要求,一次交互后要断开连接
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }





}
1.2.4DispatcherServlet
package com.webserver.core;

import com.webserver.annotations.Controller;
import com.webserver.annotations.RequestMapping;
import com.webserver.controller.ArticleController;
import com.webserver.controller.ToolsController;
import com.webserver.controller.UserController;
import com.webserver.http.HttpServletRequest;
import com.webserver.http.HttpServletResponse;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.nio.file.Files;


public class DispatcherServlet {
    private static File rootDir;
    private static File staticDir;

    static {
        try {
            rootDir = new File(
                    ClientHandler.class.getClassLoader()
                            .getResource(".").toURI()
            );
            staticDir = new File(rootDir, "static");
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }

    public void service(HttpServletRequest request, HttpServletResponse response) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException {
        String path = request.getRequestURI();
        //根据请求路径判断是否为处理某个业务
        
        File dir = new File(rootDir,"/com/webserver/controller");
        File[] files = dir.listFiles(f->f.getName().endsWith(".class"));
        for(File file : files){
            String fileName = file.getName();
            String className = fileName.substring(0,fileName.indexOf("."));
            Class cls = Class.forName("com.webserver.controller."+className);
            //判断当前类是否为Controller(是否被@Controller标注)
            if(cls.isAnnotationPresent(Controller.class)){
                //获取该类中所有方法
                Method[] methods = cls.getDeclaredMethods();
                for(Method method : methods){
                    //判断当前方法是否为处理业务的方法(是否被@RequestMapping标注)
                    if(method.isAnnotationPresent(RequestMapping.class)){
                        //获取注解@RequestMapping
                        RequestMapping rm = method.getAnnotation(RequestMapping.class);
                        String value = rm.value();
                        //判断该注解上的参数值是否与本次请求路径一致?若一致说明就是该方法处理这个请求
                        if(value.equals(path)){
                            //实例化当前Controller
                            Object controller = cls.newInstance();
                            //调用当前方法处理该请求
                            method.invoke(controller,request,response);
                            return;//当业务处理完毕直接return,防止执行下面请求静态资源的逻辑
                        }
                    }
                }
            }

        }



        File file = new File(staticDir, path);
        System.out.println("资源是否存在:" + file.exists());
        if (file.isFile()) {
            //将请求的实际文件设置到response的正文上等待响应
            response.setContentFile(file);
        } else {
            file = new File(staticDir, "/root/404.html");
            //将404内容设置到response上等待响应
            response.setStatusCode(404);
            response.setStatusReason("NotFound");
            response.setContentFile(file);
        }

    }
}
1.3HTML文件

和之前的版本一样

2.V26版本
重构代码
上一个版本那种DispatcherServlet每次处理请求时都要扫描controller包,这样性能
底下.因此改为仅扫描一次.

实现:
1:在com.webserver.core包下新建类HandlerMapping
2:定义静态属性Map mapping
  key:请求路径
  value:MethodMapping(内部类),记录处理该请求的方法对象和该方法所属对象
3:在静态块中初始化,完成原DispatcherServlet扫描controller包的工作并初始化map
4:提供静态方法:getMethod可根据请求路径获取处理该请求的方法
5:在DispatcherServlet中处理业务时只需要根据请求获取对应的处理方法利用反射
  机制调用即可
2.1项目目录

 2.2Java文件 2.2.1ClientHandler
package com.webserver.core;

import com.webserver.http.EmptyRequestException;
import com.webserver.http.HttpServletRequest;
import com.webserver.http.HttpServletResponse;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.net.Socket;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;


public class ClientHandler implements Runnable{
    private Socket socket;
    public ClientHandler(Socket socket){
        this.socket = socket;
    }

    public void run() {
        try {
            //1解析请求
            HttpServletRequest request = new HttpServletRequest(socket);
            HttpServletResponse response = new HttpServletResponse(socket);

            //2处理请求
            DispatcherServlet servlet = new DispatcherServlet();
            servlet.service(request,response);

            //3发送响应
            response.response();



        } catch (IOException e) {
            e.printStackTrace();
        } catch (EmptyRequestException e) {

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } finally {
            try {
                //按照HTTP协议要求,一次交互后要断开连接
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }





}
2.2.2DispatcherServlet
package com.webserver.core;

import com.webserver.annotations.Controller;
import com.webserver.annotations.RequestMapping;
import com.webserver.controller.ArticleController;
import com.webserver.controller.ToolsController;
import com.webserver.controller.UserController;
import com.webserver.http.HttpServletRequest;
import com.webserver.http.HttpServletResponse;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.nio.file.Files;


public class DispatcherServlet {
    private static File rootDir;
    private static File staticDir;

    static {
        try {
            rootDir = new File(
                    ClientHandler.class.getClassLoader()
                            .getResource(".").toURI()
            );
            staticDir = new File(rootDir, "static");
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }

    public void service(HttpServletRequest request, HttpServletResponse response) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException {
        String path = request.getRequestURI();
        //path:/myweb/index.html
        //判断当前请求是否为请求业务
        HandlerMapping.MethodMapping mm = HandlerMapping.getMethod(path);
        if(mm!=null){
            Method method = mm.getMethod();
            Object controller = mm.getController();
            method.invoke(controller,request,response);
            return;
        }

        File file = new File(staticDir, path);
        System.out.println("资源是否存在:" + file.exists());
        if (file.isFile()) {
            //将请求的实际文件设置到response的正文上等待响应
            response.setContentFile(file);
        } else {
            file = new File(staticDir, "/root/404.html");
            //将404内容设置到response上等待响应
            response.setStatusCode(404);
            response.setStatusReason("NotFound");
            response.setContentFile(file);
        }

    }
}
2.2.3HandlerMapping
package com.webserver.core;

import com.webserver.annotations.Controller;
import com.webserver.annotations.RequestMapping;

import java.io.File;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;


public class HandlerMapping {
    public static Map mapping = new HashMap();
    static{
        initMapping();
    }
    private static void initMapping(){
        try {
            File rootDir = new File(HandlerMapping.class.getClassLoader().
                                    getResource(".").toURI());
            File dir = new File(rootDir,"/com/webserver/controller");
            File[] files = dir.listFiles(f->f.getName().endsWith(".class"));
            for(File file : files){
                String fileName = file.getName();
                String className = fileName.substring(0,fileName.indexOf("."));
                Class cls = Class.forName("com.webserver.controller."+className);
                //判断当前类是否为Controller(是否被@Controller标注)
                if(cls.isAnnotationPresent(Controller.class)){
                    //将该Controller实例化
                    Object controller = cls.newInstance();
                    //获取该类中所有方法
                    Method[] methods = cls.getDeclaredMethods();
                    for(Method method : methods){
                        //判断当前方法是否为处理业务的方法(是否被@RequestMapping标注)
                        if(method.isAnnotationPresent(RequestMapping.class)){
                            //获取注解@RequestMapping
                            RequestMapping rm = method.getAnnotation(RequestMapping.class);
                            
                            String value = rm.value();//该方法处理的请求路径
                            MethodMapping mm = new MethodMapping(method,controller);
                            mapping.put(value,mm);
                        }
                    }
                }
            }
        } catch (URISyntaxException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    
    public static MethodMapping getMethod(String uri){
        return mapping.get(uri);
    }

    public static void main(String[] args) {
        mapping.forEach(
                (k,v)->{
                    System.out.println("请求路径"+k);
                    System.out.println("对应的处理方法:"+v.getMethod().getName());
                }
        );
    }


    public static class MethodMapping{
        //method.invoke(controller,...);
        private Method method;      //方法对象
        private Object controller;  //方法所属的Controller对象

        public MethodMapping(Method method, Object controller) {
            this.method = method;
            this.controller = controller;
        }

        public Method getMethod() {
            return method;
        }

        public Object getController() {
            return controller;
        }
    }
}







2.3HTML文件

没有改动

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/988145.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号