Spring GraphQL无法填充Record类型UserInput引发空指针异常求助
Spring Boot GraphQL 创建用户Mutation出现NullPointerException的排查方案
问题描述
使用Spring Boot GraphQL开发媒体追踪器时,执行创建用户的Mutation请求抛出NullPointerException,调试发现registerUser方法中的UserInput参数为null,无法调用其password()方法。
相关代码
请求内容
mutation User { registerUser( user: { username: "Biga", email: "biga@email.com", password: "test" } ) { username } }
GraphQL Schema(user.graphqls)
type Query { findUserByUsername(username: String!): User findUserById(id: ID!): User findUserByEmail(email: String!): User } type Mutation { registerUser(user: UserInput!): User } type User { id: ID username: String email: String } input UserInput { username: String! email: String! password: String! }
UserInput Record类
package com.espacogeek.geek.inputs; public record UserInput(String username, String email, String password) {}
UserController控制器
package com.espacogeek.geek.controllers; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.graphql.data.method.annotation.Argument; import org.springframework.graphql.data.method.annotation.MutationMapping; import org.springframework.stereotype.Controller; import com.espacogeek.geek.inputs.UserInput; import com.espacogeek.geek.modals.UserModal; import com.espacogeek.geek.services.User.UserService; import at.favre.lib.crypto.bcrypt.BCrypt; @Controller public class UserController { @Autowired private UserService userService; //Some codes... @MutationMapping public UserModal registerUser(@Argument UserInput userInput) { var passwordCrypted = BCrypt.withDefaults().hash(12, userInput.password().toCharArray()); UserModal user = new UserModal(null, userInput.username(), userInput.email(), passwordCrypted); return userService.save(user); } }
问题原因与解决方案
核心问题
@Argument注解的参数名与GraphQL Schema中定义的参数名不匹配:
- Schema里
registerUser的参数名为user - 控制器方法中参数名为
userInput,且未显式指定匹配的Schema参数名
Spring GraphQL默认通过方法参数名匹配Schema中的参数名,但如果编译时参数名被优化(比如开启了Java编译的参数名去除),或者参数名本身不对应,就会导致参数绑定失败,UserInput对象为null。
修复代码
修改控制器的registerUser方法,在@Argument注解中显式指定Schema中的参数名user:
@MutationMapping public UserModal registerUser(@Argument("user") UserInput userInput) { var passwordCrypted = BCrypt.withDefaults().hash(12, userInput.password().toCharArray()); UserModal user = new UserModal(null, userInput.username(), userInput.email(), passwordCrypted); return userService.save(user); }
验证方案
修改后重新执行Mutation请求,Spring GraphQL会正确将请求中的user参数绑定到userInput对象,避免NullPointerException。
内容的提问来源于stack exchange,提问作者Vitor Hugo
相关产品推荐
相关产品推荐

