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

Java注解避免硬编码报错:Attribute value must be constant解决方案

解决方案:注解中使用非常量URL的问题

问题原因

Java注解的属性值要求是编译时常量表达式,你原来的UrlsParts.deleteById是通过静态方法GeneralUtils.getUrlWithId()赋值的,这类方法调用不属于编译时常量,因此无法在@PostMapping这类注解中使用。

可行解决方案

方案1:直接常量字符串拼接

最简单的处理方式,直接通过字符串拼接定义常量,这种拼接操作属于编译时常量,完全符合注解的参数要求:

public class UrlsParts {   
    public static final String delete = "/delete";
    // 直接拼接,编译期即可确定最终值
    public static final String deleteById = delete + "/{id}";
}

Controller中直接引用即可:

@PostMapping(UrlsParts.deleteById)
public String delete(@PathVariable Integer id, Model model) {
    authorRepository.deleteById(id);
    return "redirect:" + Urls.AUTHORS_LIST.getHref();
}

方案2:枚举统一管理URL

用枚举封装所有URL,枚举的成员属性属于编译时常量,同时可以通过Spring的SpEL表达式在注解中引用,适合URL数量多、需要统一维护的场景:

public enum UrlsParts {
    // 直接定义所有URL常量
    DELETE("/delete"),
    DELETE_BY_ID("/delete/{id}");

    private final String value;

    UrlsParts(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }
}

Controller中通过SpEL的T()表达式引用枚举值(注意替换为你的枚举类完整包路径):

@PostMapping("#{T(com.yourproject.UrlsParts).DELETE_BY_ID.getValue()}")
public String delete(@PathVariable Integer id, Model model) {
    authorRepository.deleteById(id);
    return "redirect:" + Urls.AUTHORS_LIST.getHref();
}

这种方式还可以给枚举扩展更多属性,比如接口描述、请求方法类型等,扩展性更强。

方案3:接口定义常量(语法可行但不推荐)

接口中的成员默认是public static final,也可以直接拼接定义常量,语法上合法但不符合Java接口的设计初衷(接口应为行为规范定义,而非常量容器),仅作为备选:

public interface UrlsParts {
    String DELETE = "/delete";
    String DELETE_BY_ID = DELETE + "/{id}";
}

Controller中直接引用:

@PostMapping(UrlsParts.DELETE_BY_ID)
public String delete(@PathVariable Integer id, Model model) {
    authorRepository.deleteById(id);
    return "redirect:" + Urls.AUTHORS_LIST.getHref();
}

内容的提问来源于stack exchange,提问作者Kifsif

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 09:42:50