You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 04:14:52