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

Enum转换报错:No enum constant问题排查与修复求助

问题排查与修复方案

错误根源

报错「No enum constant com.edd.bookrental.models.user.Role."ADMIN"」的核心原因是请求体解析后传入Role.valueOf()的字符串带双引号:

  • 当直接传"ADMIN"时,@RequestBody String role接收的实际内容是带双引号的字符串(如"\"ADMIN\""),调用trim()后仍为"ADMIN"(含引号),而枚举常量是ADMIN(无引号),匹配失败。
  • 当传{"role": "ADMIN"}时,接收的是整个JSON字符串(如"{\"role\": \"ADMIN\"}"),解析后完全不符合枚举常量格式,直接触发错误。

修复方案

方案1:改用DTO类接收JSON请求(推荐)

这是REST接口的标准做法,能正确解析JSON格式的请求体:

  1. 创建请求DTO类:
public class RoleAssignRequest {
    private String role;

    // Getter & Setter
    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }
}
  1. 修改Controller层代码:
/** Admin can assign roles to other users **/
@PostMapping(path = "/user/{id}/role")
public ResponseEntity<?> updateUserRole(@PathVariable Long id, @RequestBody RoleAssignRequest request) {
    try {
        // 清理角色字符串:转大写+去空格
        String roleStr = request.getRole().toUpperCase().trim();
        Role parsedRole = Role.valueOf(roleStr);
        
        userService.assignRole(id, parsedRole);         
        return new ResponseEntity<>(parsedRole, HttpStatus.ACCEPTED);
    } catch (IllegalArgumentException e) {
        return new ResponseEntity<>("无效角色类型:" + request.getRole(), HttpStatus.BAD_REQUEST);
    } catch (Exception e) {
        return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
    }
}

此时前端传{"role": "ADMIN"}就能被正确解析,Spring会自动将JSON中的role字段映射到DTO的role属性。

方案2:兼容纯文本请求(带/不带引号)

如果需要支持直接传纯文本(如ADMIN或"ADMIN"),可以在Controller中先清理字符串的引号:

@PostMapping(path = "/user/{id}/role")
public ResponseEntity<?> updateUserRole(@PathVariable Long id, @RequestBody String role) {
    try {
        // 去除前后双引号,转大写+去空格
        String cleanRole = role.replaceAll("^\"|\"$", "").toUpperCase().trim();
        Role parsedRole = Role.valueOf(cleanRole);
        
        userService.assignRole(id, parsedRole);         
        return new ResponseEntity<>(parsedRole, HttpStatus.ACCEPTED);
    } catch (IllegalArgumentException e) {
        return new ResponseEntity<>("无效角色类型:" + role, HttpStatus.BAD_REQUEST);
    } catch (Exception e) {
        return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
    }
}

方案3:增强枚举的解析灵活性(可选)

在枚举类中添加自定义解析方法,同时支持匹配枚举名(ADMIN)和roleText(admin),并自动处理引号:

@Getter
public enum Role {
    USER("user"), ADMIN("admin");

    String roleText;

    Role(String roleText) {
        this.roleText = roleText;
    }

    public static Role fromString(String input) {
        if (input == null) {
            throw new IllegalArgumentException("角色不能为空");
        }
        // 清理输入:去引号、转小写、去空格
        String cleaned = input.replaceAll("^\"|\"$", "").trim().toLowerCase();
        for (Role role : Role.values()) {
            // 匹配枚举名(忽略大小写)或roleText
            if (role.name().toLowerCase().equals(cleaned) || role.roleText.equals(cleaned)) {
                return role;
            }
        }
        throw new IllegalArgumentException("No enum constant for role: " + input);
    }
}

然后在Controller中替换Role.valueOf()为Role.fromString()即可。

验证注意事项

  • 发送JSON请求时,确保Postman的Content-Type设置为application/json。
  • 若使用纯文本请求,设置Content-Type为text/plain。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 15:08:14