Rumah  >  Artikel  >  Java  >  Bagaimana untuk menyesuaikan liputan penghalaan dalam SpringBoot

Bagaimana untuk menyesuaikan liputan penghalaan dalam SpringBoot

王林
王林ke hadapan
2023-05-10 16:43:131359semak imbas

    Latar Belakang

    Syarikat itu baru-baru ini mempunyai projek dalam fasa kedua yang memerlukan transformasi beberapa fungsi, yang melibatkan penyesuaian peribadi beberapa daripada terbina- dalam antara muka perniagaan rangka kerja dan keserasian dengan fungsi antara muka lama Dan menambah beberapa pemulangan data baharu Memandangkan panggilan bahagian hadapan, antara muka ini berselerak dan berpecah-belah, dan kos pengubahsuaian dan ujian adalah tinggi, kami merancang untuk menyediakan fungsi liputan penghalaan di bahagian. tahap rangka kerja untuk mempercepatkan kemajuan projek dan mengurangkan risiko sistem yang disebabkan oleh pengubahsuaian tanpa kandungan teknikal

    Reka bentuk

    • Sediakan anotasi tersuai untuk menentukan laluan dan alamat penghalaan baharu. yang perlu dilindungi

    • Imbas semua anotasi apabila sistem memulakan pemprosesan Data dan pemetaan

    • Daftar kelas konfigurasi pemetaan laluan tersuai

    Pelaksanaan

    Takrifan anotasi

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    public @interface CoverRoute {
        String value() default "";
    }

    Pengimbasan dan pengurusan anotasi

    Panggil kaedah initRoute apabila sistem mula memetakan laluan asal dan yang sepadan laluan tindanan ke pasangan nilai kunci peta

    public class ConverRouteUtil {
        private static HashMap<String, String> mappingRegist = new HashMap<>();
        public static void initRoute(Class runtimeClass, List<String> extraPackageNameList) {
            List<Class<?>> scanClassList = new ArrayList<>();
            if (!runtimeClass.getPackage().getName().equals(Application.class.getPackage().getName())) {
                scanClassList.addAll(ScanUtil.getAllClassByPackageName_Annotation(runtimeClass.getPackage(), CoverRoute.class));
            }
            for (String packageName : extraPackageNameList) {
                scanClassList.addAll(ScanUtil.getAllClassByPackageName_Annotation(packageName, CoverRoute.class));
            }
            for (Class clazz : scanClassList) {
                CoverRoute coverRoute = (CoverRoute) clazz.getAnnotation(CoverRoute.class);
                if (StringUtil.isEmpty(coverRoute.value())) {
                    continue;
                }
                RequestMapping requestMapping = (RequestMapping) clazz.getAnnotation(RequestMapping.class);
                String classRoute = "";
                if (requestMapping != null) {
                    classRoute = requestMapping.value()[0];
                } else {
                    continue;
                }
                List<Method> methodList = Arrays.asList(clazz.getDeclaredMethods());
                for (Method method : methodList) {
                    PostMapping postMapping = method.getAnnotation(PostMapping.class);
                    String methodRoute = "";
                    if (postMapping != null) {
                        methodRoute = postMapping.value()[0];
                    } else {
                        GetMapping getMapping = method.getAnnotation(GetMapping.class);
                        if (getMapping != null) {
                            methodRoute = getMapping.value()[0];
                        }
                    }
                    if (!StringUtil.isEmpty(classRoute) && !StringUtil.isEmpty(methodRoute)) {
                        String orginalRoute = coverRoute.value() + methodRoute;
                        String redirectRoute = classRoute + methodRoute;
                        mappingRegist.put(orginalRoute, redirectRoute);
                    }
                }
            }
            if (mappingRegist.size() > 0) {
                System.out.println("扫描路由方法覆盖:" + mappingRegist.size() + "个");
            }
        }
        public static boolean checkExistCover(String orginalRoute) {
            return mappingRegist.containsKey(orginalRoute);
        }
        public static String getRedirectRoute(String orginalRoute) {
            return mappingRegist.get(orginalRoute);
        }
    }

    PermintaanMappingHandlerMapping Tersuai

    Warisi RequestMappingHandlerMapping dan tulis semula kaedah lookupHandlerMethod untuk menulis gantinya apabila musim bunga melakukan penghalaan

    RequestMappingHandlerMapping

    public class CustomRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
        @Override
        protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
            if(ConverRouteUtil.checkExistCover(lookupPath)){
                String redirectRoute = ConverRouteUtil.getRedirectRoute(lookupPath);
                request.setAttribute("redirectTag","1");
                request.setAttribute("redirectRoute",redirectRoute);
                request.setAttribute("lookupPath",lookupPath);
                lookupPath = redirectRoute;
            }else{
                request.setAttribute("redirectTag","0");
            }
            return super.lookupHandlerMethod(lookupPath, request);
        }
        @Override
        protected RequestMappingInfo getMatchingMapping(RequestMappingInfo info, HttpServletRequest request) {
            String redirectTag = ConvertOp.convert2String(request.getAttribute("redirectTag"));
            if(redirectTag.equals("1")){
                String redirectRoute = ConvertOp.convert2String(request.getAttribute("redirectRoute"));
                boolean check = false;
                if( info.getPatternsCondition()!=null){
                    Set<String> set =  info.getPatternsCondition().getPatterns();
                    if(set.size()>0){
                        String[] array = new String[set.size()];
                        array = set.toArray(array);
                        String pattern = array[0];
                        if(pattern.equals(redirectRoute)){
                            check = true;
                        }
                    }
                }
                if(check){
                    return info;
                }else{
                    return super.getMatchingMapping(info, request);
                }
            }else{
                return super.getMatchingMapping(info, request);
            }
        }
    }
    >🎜>
    @Component
    public class WebRequestMappingConfig implements WebMvcRegistrations {
        public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
            RequestMappingHandlerMapping handlerMapping = new CustomRequestMappingHandlerMapping();
            handlerMapping.setOrder(0);
            return handlerMapping;
        }
    }
    @Controller
    @RequestMapping("/example/original")
    public class RedirectOriginalExampleController {
        @PostMapping("/getConfig")
        @ResponseBody
        @AnonymousAccess
        public Object getConfig(@RequestBody Map<String, Object> params) {
            Result result = Result.okResult();
            result.add("tag","original");
            return result;
        }
    }

    Contoh penggunaan

    Tambah anotasi @CoverRoute ke kelas antara muka yang diperibadikan , nyatakan alamat penghalaan yang perlu dilindungi dan buat laluan penghalaan yang sama Akses ke alamat antara muka asal akan dimajukan secara automatik ke alamat antara muka diperibadikan projek

    Antara muka asal

    @Controller
    @RequestMapping("/example/redirect")
    @CoverRoute("/example/original")
    public class RedirectExampleController {
        @PostMapping("/getConfig")
        @ResponseBody
        public Object getConfig(@RequestBody Map<String, Object> params) {
            Result result = Result.okResult();
            String param1 = ConvertOp.convert2String(params.get("param1"));
            result.add("tag","redirect");
            result.add("param1",param1);
            return result;
        }
    }

    Antara muka baharu

    rrreee

    Atas ialah kandungan terperinci Bagaimana untuk menyesuaikan liputan penghalaan dalam SpringBoot. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

    Kenyataan:
    Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam