欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot自定義路由覆蓋實(shí)現(xiàn)流程詳解

 更新時(shí)間:2023年01月02日 09:42:33   作者:code2roc  
這篇文章主要介紹了SpringBoot自定義路由覆蓋實(shí)現(xiàn)流程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧

背景

公司最近有一個(gè)項(xiàng)目二期需要對(duì)一些功能進(jìn)行改造,涉及部分框架內(nèi)置業(yè)務(wù)接口個(gè)性化定制,兼容老接口功能并且增加一部分新的數(shù)據(jù)返回,由于前端調(diào)用這些接口分布較多且較為零碎,修改測試成本較大,所以打算在框架層面提供路由覆蓋功能,加快項(xiàng)目進(jìn)度減少無技術(shù)含量的修改帶來的系統(tǒng)風(fēng)險(xiǎn)

設(shè)計(jì)

  • 提供自定義注解指定需要覆蓋的路由及新路由地址
  • 系統(tǒng)啟動(dòng)時(shí)掃描所有注解數(shù)據(jù)并進(jìn)行映射處理
  • 注冊(cè)自定義路由映射配置類

實(shí)現(xiàn)

注解定義

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

注解掃描及管理

在系統(tǒng)啟動(dòng)時(shí)調(diào)用initRoute方法,把原路由和對(duì)應(yīng)的覆蓋路由映射到map鍵值對(duì)中

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() + "個(gè)");
        }
    }
    public static boolean checkExistCover(String orginalRoute) {
        return mappingRegist.containsKey(orginalRoute);
    }
    public static String getRedirectRoute(String orginalRoute) {
        return mappingRegist.get(orginalRoute);
    }
}

自定義RequestMappingHandlerMapping

繼承RequestMappingHandlerMapping重寫lookupHandlerMethod方法,在spring進(jìn)行路由尋址時(shí)進(jìn)行覆蓋

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);
        }
    }
}

注冊(cè)RequestMappingHandlerMapping

@Component
public class WebRequestMappingConfig implements WebMvcRegistrations {
    public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
        RequestMappingHandlerMapping handlerMapping = new CustomRequestMappingHandlerMapping();
        handlerMapping.setOrder(0);
        return handlerMapping;
    }
}

使用示例

在個(gè)性化接口類增加@CoverRoute注解,指定需要覆蓋的路由地址,創(chuàng)建相同路由路徑的的方法即可,訪問原來的接口地址會(huì)自動(dòng)轉(zhuǎn)發(fā)到項(xiàng)目個(gè)性化接口地址

原接口

@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;
    }
}

新接口

@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;
    }
}

到此這篇關(guān)于SpringBoot自定義路由覆蓋實(shí)現(xiàn)流程詳解的文章就介紹到這了,更多相關(guān)SpringBoot自定義路由覆蓋內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java生成二維碼的兩種實(shí)現(xiàn)方式(基于Spring?Boot)

    Java生成二維碼的兩種實(shí)現(xiàn)方式(基于Spring?Boot)

    這篇文章主要給大家介紹了關(guān)于Java生成二維碼的兩種實(shí)現(xiàn)方式,文中的代碼基于Spring?Boot,本文基于JAVA環(huán)境,以SpringBoot框架為基礎(chǔ)開發(fā),文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • maven 指定version不生效的問題

    maven 指定version不生效的問題

    這篇文章主要介紹了maven 指定version不生效的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • java 使用ImageIO.writer從BufferedImage生成jpeg圖像遇到問題總結(jié)及解決

    java 使用ImageIO.writer從BufferedImage生成jpeg圖像遇到問題總結(jié)及解決

    這篇文章主要介紹了java 使用ImageIO.writer從BufferedImage生成jpeg圖像遇到問題總結(jié)及解決的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • SpringBoot使用Kaptcha實(shí)現(xiàn)驗(yàn)證碼的生成與驗(yàn)證功能

    SpringBoot使用Kaptcha實(shí)現(xiàn)驗(yàn)證碼的生成與驗(yàn)證功能

    這篇文章主要介紹了SpringBoot使用Kaptcha實(shí)現(xiàn)驗(yàn)證碼的生成與驗(yàn)證功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-03-03
  • Springboot實(shí)現(xiàn)動(dòng)態(tài)定時(shí)任務(wù)流程詳解

    Springboot實(shí)現(xiàn)動(dòng)態(tài)定時(shí)任務(wù)流程詳解

    通過重寫SchedulingConfigurer方法實(shí)現(xiàn)對(duì)定時(shí)任務(wù)的操作,單次執(zhí)行、停止、啟動(dòng)三個(gè)主要的基本功能,動(dòng)態(tài)的從數(shù)據(jù)庫中獲取配置的定時(shí)任務(wù)cron信息,通過反射的方式靈活定位到具體的類與方法中
    2022-09-09
  • java數(shù)據(jù)結(jié)構(gòu)排序算法之樹形選擇排序詳解

    java數(shù)據(jù)結(jié)構(gòu)排序算法之樹形選擇排序詳解

    這篇文章主要介紹了java數(shù)據(jù)結(jié)構(gòu)排序算法之樹形選擇排序,結(jié)合具體實(shí)例形式分析了java樹形選擇排序的原理、實(shí)現(xiàn)技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2017-05-05
  • 與近日火爆的ChatGPT聊Elasticsearch源碼

    與近日火爆的ChatGPT聊Elasticsearch源碼

    這篇文章主要為大家分享了與近日火爆的ChatGPT聊Elasticsearch源碼的話題內(nèi)容,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • Java自定義映射resultMap定義及用法

    Java自定義映射resultMap定義及用法

    MyBatis的每一個(gè)查詢映射的返回類型都是ResultMap,當(dāng)我們提供返回類型屬性是resultType時(shí),MyBatis會(huì)自動(dòng)給我們把對(duì)應(yīng)值賦給resultType所指定對(duì)象的屬性,當(dāng)我們提供返回類型是resultMap時(shí),將數(shù)據(jù)庫中列數(shù)據(jù)復(fù)制到對(duì)象的相應(yīng)屬性上,可以用于復(fù)制查詢,兩者不能同時(shí)用
    2022-11-11
  • Java LinkedHashMap深入分析源碼

    Java LinkedHashMap深入分析源碼

    大多數(shù)情況下,只要不涉及線程安全問題,Map基本都可以使用HashMap,不過HashMap有一個(gè)問題,就是迭代HashMap的順序并不是HashMap放置的順序,也就是無序。HashMap的這一缺點(diǎn)往往會(huì)帶來困擾,所以LinkedHashMap就閃亮登場了,這篇文章通過源碼解析帶你了解LinkedHashMap
    2022-11-11
  • Java中的泛型和泛型通配符詳解

    Java中的泛型和泛型通配符詳解

    這篇文章主要介紹了Java中的泛型和泛型通配符詳解,泛型的作用就是在編譯的時(shí)候能夠檢查類型安全,并且所有的強(qiáng)制轉(zhuǎn)換都是自動(dòng)和隱式的在沒有泛型的情況的下,通過對(duì)類型Object的引用來實(shí)現(xiàn)參數(shù)的“任意化”,需要的朋友可以參考下
    2023-07-07

最新評(píng)論