Java:SpringBoot给Controller添加统一路由前缀

您所在的位置:网站首页 统一支付接口管理怎么设置 Java:SpringBoot给Controller添加统一路由前缀

Java:SpringBoot给Controller添加统一路由前缀

2024-07-15 00:25| 来源: 网络整理| 查看: 265

网上的文章五花八门,不写SpringBoot的版本号,导致代码拿来主义不好使了。

本文采用的版本

SpringBoot 2.7.7 Java 1.8

目录 1、默认访问路径2、整个项目增加路由前缀3、通过注解方式增加路由前缀4、按照目录结构/包名添加前缀总结参考文章

1、默认访问路径 package com.example.demo.controller.api; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api") public class AppIndexController { @GetMapping("/index") public String index() { return "app"; } }

访问地址:http://localhost:8080/api/index

2、整个项目增加路由前缀

application.yml

server: servlet: context-path: /prefix

访问地址:http://localhost:8080/prefix/api/index

注意:该方案会将所有的路由都增加一个前缀

3、通过注解方式增加路由前缀

注解

package com.example.demo.annotation; import org.springframework.core.annotation.AliasFor; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RestController; import java.lang.annotation.*; /** * controller层统一使用该注解 */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @RestController public @interface ApiRestController { /** * Alias for {@link Controller#value}. */ @AliasFor(annotation = Controller.class) String value() default ""; }

配置

package com.example.demo.config; import com.example.demo.annotation.ApiRestController; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * 配置统一的后台接口访问路径的前缀 */ @Configuration public class CustomWebMvcConfig implements WebMvcConfigurer { @Override public void configurePathMatch(PathMatchConfigurer configurer) { configurer .addPathPrefix("/api", c -> c.isAnnotationPresent(ApiRestController.class)); } }

使用注解

package com.example.demo.controller.api; import com.example.demo.annotation.ApiRestController; import org.springframework.web.bind.annotation.GetMapping; @ApiRestController // @RestController // @RequestMapping("/api") public class AppIndexController { @GetMapping("/index") public String index() { return "app"; } }

访问地址:http://localhost:8080/api/index

4、按照目录结构/包名添加前缀

没有成功,可能是版本的问题

按照网上的实现方式

// 核心代码 RequestMappingInfo.paths(prefix).build().combine(mappingInfo);

会报错

Neither PathPatterns nor String patterns condition

2023年6月9日补充

感谢评论区的大佬 @孤独和弦 帮助,补充第四种方式

思路:

将原有路由的所有路径取出,手动拼接前缀,再和原有路由配置合并

项目结构

$ tree -I target -I test . ├── pom.xml └── src └── main ├── java │ └── com │ └── example │ └── demo │ ├── Application.java │ ├── config │ │ ├── AutoPrefixConfiguration.java │ │ └── AutoPrefixUrlMapping.java │ └── controller │ └── v1 │ └── IndexController.java └── resources ├── application.yml ├── static └── templates

配置 application.yml

# 需要添加路径前缀的包名 api-package: com.example.demo.controller

AutoPrefixUrlMapping.java

package com.example.demo.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import java.lang.reflect.Method; import java.util.Objects; /** * 自动补全路由前缀处理类 */ public class AutoPrefixUrlMapping extends RequestMappingHandlerMapping { /** * 读取基础包配置 */ @Value("${api-package}") private String bathApiPackagePath; /** * 重写方法路由获取 * * @param method * @param handlerType * @return */ @Override protected RequestMappingInfo getMappingForMethod(Method method, Class handlerType) { RequestMappingInfo mappingInfo = super.getMappingForMethod(method, handlerType); if (Objects.nonNull(mappingInfo)) { String prefix = this.getPrefix(handlerType); if (prefix != null) { String[] paths = mappingInfo.getPatternValues() .stream() .map(path -> prefix + path) .toArray(String[]::new); return mappingInfo.mutate() .paths(paths) .build(); } } return mappingInfo; } /** * 获取方法路由前缀 * * @param handleType * @return */ private String getPrefix(Class handleType) { String packageName = handleType.getPackage().getName(); // 如果包含指定的包则返回前缀 if (packageName.startsWith(this.bathApiPackagePath)) { return packageName.substring(this.bathApiPackagePath.length()) .replace(".", "/"); } else { return null; } } }

AutoPrefixConfiguration.java

package com.example.demo.config; import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations; import org.springframework.stereotype.Component; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; /** * 自动补全路由前缀配置类 */ @Component public class AutoPrefixConfiguration implements WebMvcRegistrations { @Override public RequestMappingHandlerMapping getRequestMappingHandlerMapping() { return new AutoPrefixUrlMapping(); } }

控制器

package com.example.demo.controller.v1; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api") public class IndexController { @GetMapping("/index") public String index() { return "Hello"; } }

访问路径:http://localhost:8080/v1/api/index

总结 方 式适用范围RequestMapping/PostMapping/GetMapping单个方法 或 单个类(多个方法)自定义注解多个控制器(可以不同目录)目录 / 包名 前缀多个控制器(同目录)配置 context-path全局前缀

包名前缀只能是符合java包名规范的才可以,比如中划线就不行,需要修改代码自定义做映射

参考文章 SpringBoot2.x 给Controller的RequestMapping添加统一前缀SpringBoot - 根据目录结构自动生成路由前缀


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3