如何在Spring REST控制器中强制执行连字符式URL命名规范?
强制执行Spring REST API连字符命名规范的Maven构建校验方案
要在Maven构建阶段强制Spring REST API使用小写连字符的命名规范(路径如/store-users、参数如first-name),核心是通过静态代码分析工具扫描控制器注解,一旦发现驼峰格式的路径或参数就终止构建。以下是两种可直接落地的方案:
方案一:用Checkstyle快速实现自定义规则
Checkstyle自带注解属性检查能力,无需编写Java代码,仅通过配置文件即可完成规则定义。
1. 配置Maven Checkstyle插件
在项目pom.xml中添加插件,绑定到构建的validate阶段,确保构建前自动执行检查:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-checkstyle-plugin</artifactId> <version>3.3.0</version> <executions> <execution> <id>enforce-api-naming</id> <phase>validate</phase> <goals> <goal>check</goal> </goals> </execution> </executions> <configuration> <configLocation>checkstyle-api-rules.xml</configLocation> <failOnError>true</failOnError> <!-- 检查失败直接终止构建 --> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build>
2. 编写Checkstyle规则文件
在项目根目录创建checkstyle-api-rules.xml,定义两个核心规则:
- 扫描所有Spring请求映射注解(
@GetMapping/@PostMapping等)的路径属性,确保是小写连字符格式 - 扫描
@RequestParam的参数名属性,确保是小写连字符格式
<?xml version="1.0"?> <!DOCTYPE module PUBLIC "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN" "https://checkstyle.org/dtds/configuration_1_3.dtd"> <module name="Checker"> <property name="charset" value="UTF-8"/> <module name="TreeWalker"> <!-- 检查API路径命名规范 --> <module name="AnnotationPropertyCheck"> <property name="annotationNames" value="org.springframework.web.bind.annotation.RequestMapping,org.springframework.web.bind.annotation.GetMapping,org.springframework.web.bind.annotation.PostMapping,org.springframework.web.bind.annotation.PutMapping,org.springframework.web.bind.annotation.DeleteMapping"/> <property name="propertyNames" value="value,path"/> <!-- 正则:允许开头/结尾斜杠,仅包含小写字母、数字、连字符 --> <property name="regexp" value="^\/?([a-z0-9]+(-[a-z0-9]+)*)*\/?$"/> <property name="message" value="API路径必须使用小写连字符格式(如'/store-users'),当前值为'{0}'"/> </module> <!-- 检查请求参数命名规范 --> <module name="AnnotationPropertyCheck"> <property name="annotationNames" value="org.springframework.web.bind.annotation.RequestParam"/> <property name="propertyNames" value="value,name"/> <!-- 正则:仅包含小写字母、数字、连字符,无特殊字符 --> <property name="regexp" value="^[a-z0-9]+(-[a-z0-9]+)*$"/> <property name="message" value="请求参数名必须使用小写连字符格式(如'first-name'),当前值为'{0}'"/> </module> </module> </module>
方案二:用PMD编写自定义Java规则(更灵活)
如果需要更复杂的校验逻辑(比如排除特定路径、支持动态参数占位符),可以用PMD编写自定义规则类。
1. 配置Maven PMD插件
在pom.xml中添加PMD插件,同样绑定到validate阶段:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-pmd-plugin</artifactId> <version>3.21.0</version> <executions> <execution> <id>enforce-api-naming</id> <phase>validate</phase> <goals> <goal>check</goal> </goals> </execution> </executions> <configuration> <rulesets> <ruleset>pmd-api-rules.xml</ruleset> </rulesets> <failOnViolation>true</failOnViolation> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build>
2. 编写自定义PMD规则类
创建规则类,扫描Spring注解的属性值并校验格式:
import net.sourceforge.pmd.lang.java.ast.ASTAnnotation; import net.sourceforge.pmd.lang.java.ast.ASTLiteral; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule; public class ApiNamingConventionRule extends AbstractJavaRule { // 要检查的Spring映射注解 private static final String[] MAPPING_ANNOTATIONS = { "RequestMapping", "GetMapping", "PostMapping", "PutMapping", "DeleteMapping" }; // 路径校验正则:支持动态参数(如'/users/{user-id}') private static final String PATH_PATTERN = "^\\/?([a-z0-9]+(-[a-z0-9]+)*|\\{[a-z0-9]+(-[a-z0-9]+)*\\})*\\/?$"; // 参数名校验正则 private static final String PARAM_PATTERN = "^[a-z0-9]+(-[a-z0-9]+)*$"; @Override public Object visit(ASTAnnotation annotation, Object data) { String annotationName = annotation.getAnnotationType().getSimpleName(); // 检查路径注解 for (String mappingAnn : MAPPING_ANNOTATIONS) { if (mappingAnn.equals(annotationName)) { checkAnnotationProperty(annotation, "value", PATH_PATTERN, "API路径不符合小写连字符规范"); checkAnnotationProperty(annotation, "path", PATH_PATTERN, "API路径不符合小写连字符规范"); break; } } // 检查请求参数注解 if ("RequestParam".equals(annotationName)) { checkAnnotationProperty(annotation, "value", PARAM_PATTERN, "请求参数名不符合小写连字符规范"); checkAnnotationProperty(annotation, "name", PARAM_PATTERN, "请求参数名不符合小写连字符规范"); } return super.visit(annotation, data); } // 校验注解属性值 private void checkAnnotationProperty(ASTAnnotation annotation, String propertyName, String pattern, String message) { annotation.findDescendantsOfType(ASTLiteral.class).stream() .filter(lit -> lit.getParent() != null && propertyName.equals(lit.getParent().getImage())) .forEach(lit -> { String value = lit.getImage().replace("\"", ""); if (!value.matches(pattern)) { addViolationWithMessage(data, lit, message + ",当前值为'" + value + "'"); } }); } }
3. 配置PMD规则集
在项目根目录创建pmd-api-rules.xml,引入自定义规则:
<?xml version="1.0"?> <ruleset name="API Naming Convention Rules" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"> <rule name="ApiNamingConventionRule" language="java" class="com.your.project.package.ApiNamingConventionRule" message="违反API命名规范"> <description>强制API路径和请求参数使用小写连字符格式,支持动态参数占位符(如{user-id})</description> </rule> </ruleset>
落地验证
完成配置后,运行mvn validate命令,若代码中存在驼峰格式的路径(如/storeUsers)或参数(如firstName),Maven会直接终止构建并输出对应的错误信息。
对于历史遗留的不符合规范的API,可以通过@SuppressWarnings("checkstyle:annotationpropertycheck")(Checkstyle)或@SuppressWarnings("PMD.ApiNamingConventionRule")(PMD)暂时忽略,后续逐步整改。
内容的提问来源于stack exchange,提问作者dan carter
相关产品推荐
相关产品推荐

