conanan's blog conanan's blog
首页
关于
  • 分类
  • 标签
  • 归档
  • Java
  • Java Web
  • 工具

    • Maven
  • MySQL
  • Redis
  • Git
  • Vim
  • Nginx
  • Docker
GitHub

Evan Xu

前端界的小学生
首页
关于
  • 分类
  • 标签
  • 归档
  • Java
  • Java Web
  • 工具

    • Maven
  • MySQL
  • Redis
  • Git
  • Vim
  • Nginx
  • Docker
GitHub
  • Jakarta EE

  • Tomcat

  • Spring

  • SpringMVC

    • 概述
    • 路由&请求参数绑定
    • 响应结果
    • 异常处理&统一响应
    • Interceptor
    • CORS
    • 自动URL前缀
    • Jackson
  • SpringBoot

  • SpringDataJPA

  • Test
  • Shiro
  • Thymeleaf
  • Java Web
  • SpringMVC
conanan
2021-06-21

自动URL前缀

# 自动 URL 前缀

什么意思呢?

在如下项目结构中:

——top.conanan.demo
————api
——————v1
————————HelloController
——————v2
————————Hello2Controller
1
2
3
4
5
6

HelloController 如下:

@RestController
@RequestMapping("/v1/hello")
public class HelloController {

    @PostMapping("/test")
    public String test() {
        return "hello world";
    }
}
1
2
3
4
5
6
7
8
9

当我们要访问 test 接口时,请求的 url 为:host:port/v1/hello/test

那么如何不用写 v1或v2呢?

可以重写WebMvcRegistrations接口的getRequestMappingHandlerMapping()方法

@Configuration// 必须加上 @Configuration
public class AutoPrefixConfiguration implements WebMvcRegistrations {

    @Override
    public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
        return new AutoPrefixUrlMapping();
    }
}
1
2
3
4
5
6
7
8
/**
 * RequestMappingHandlerMapping Spring MVC 用于处理 @RequestMapping 的类
 */
public class AutoPrefixUrlMapping extends RequestMappingHandlerMapping {

    @Value("${missyou.api-package}")
    public String apiPackage;


    @Override
    protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {

        RequestMappingInfo requestMappingInfo = super.getMappingForMethod(method, handlerType);

        // 这里除了自己写的 @RequestMapping 等注解和系统的 /error 不为 null,其余都为 null(会自动生成需要 RequestMapping)
        if (requestMappingInfo == null){
            return null;
        }

        // 这里只拦截如 com.lin.missyou.api 的包下的 @RequestMapping,
        // 其他的 Spring 默认配置的 @RequestMapping 都直接放掉(如, /error)
        String packageName = handlerType.getPackage().getName();
        if (!packageName.startsWith(apiPackage))
            return requestMappingInfo;


        // 这里才是拦截到"自己"添加 @RequestMapping 注解的方法
        String prefix = getPrefix(handlerType);
        // 注意这里的 RequestMappingInfo 只有静态方法可以操作该类
        // combine 联合。拼接前缀和 @RequestMapping 注解的 value
        return RequestMappingInfo.paths(prefix).build().combine(requestMappingInfo);


    }

    private String getPrefix(Class<?> handlerType){
        // 获取的包名如:com.lin.missyou.api.v1
        String packageName = handlerType.getPackage().getName();
        String dotPath = packageName.replace(apiPackage, "");
        return dotPath.replaceAll("\\.", "/");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
missyou:
  api-package: com.lin.missyou.api
1
2
编辑
上次更新: 2021/06/21, 15:45:42
CORS
Jackson

← CORS Jackson→

最近更新
01
线程生命周期
07-06
02
线程安全理论
06-24
03
并发简史
06-24
更多文章>
Theme by Vdoing | Copyright © 2019-2021 Evan Xu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×