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
相关产品推荐
相关产品推荐

