Java 将主体作为控制器中的方法参数绑定到MyCustomUser类
我知道您可以在Spring控制器中轻松获得用户名,方法参数包括Java 将主体作为控制器中的方法参数绑定到MyCustomUser类,java,spring,spring-boot,Java,Spring,Spring Boot,我知道您可以在Spring控制器中轻松获得用户名,方法参数包括Principal,如: @GetMapping("/username") @ResponseBody public String currentUserName(Principal principal) { return principal.getName(); } 但我最终希望访问MyCustomUser类的成员,我使用findBy方法从存储库中实例化该类。我可以在控制器中放置一个helper方法,根据principal
Principal
,如:
@GetMapping("/username")
@ResponseBody
public String currentUserName(Principal principal) {
return principal.getName();
}
但我最终希望访问MyCustomUser
类的成员,我使用findBy
方法从存储库中实例化该类。我可以在控制器中放置一个helper方法,根据principal.getName()
执行查找并返回用户,但是我可以更进一步,直接绑定到MyCustomUser
,比如
@GetMapping("/stuff")
@ResponseBody
public String stuff(MyCustomUser user) {
return user.thing();
}
我正在研究创建一个类似()的转换器:
@组件
公共类PrincipalToMyCustomUserConverter实现转换器{
私有MyCustomUserRepository用户存储库;
public PrincipalToApplicationUserConverter(MyCustomUserRepository用户存储库){
this.userRepository=userRepository;
}
@凌驾
公共MyCustomUser转换(主要来源){
返回这个.userRepository.findByUsername(source.getName());
}
}
但是我不知道这是否是获取存储库的合适方式,我也不知道在注册转换器()时如何传递存储库。您的建议是正确的,因为您建议的转换器不合适。您的转换器可以从
Principal
类型的对象转换为MyCustomUser
类型的对象,但是,没有要转换的*Principal*
。主体注入背后的神奇之处在于Spring实际上是从SecurityContextHolder
获取的,它不是从请求中反序列化的……尽管请求中存在的字段允许Spring创建主体
。如果确实要注入MyCustomUser
,请使用ModelAttribute
<代码>模型属性可用于所有Spring控制器方法
我通常喜欢在它自己的类中保存这样的内容,所以我会定义一个类,将这个和其他@ControllerAdvice放在一个地方,类似这样:
@ControllerAdvice
public class SomeControllerAdvice {
@Autowired
private MyCustomUserRepository myCustomUserRepository;
@ModelAttribute
public MyCustomUser getUser(Principal principal) {
return myCustomUserRepository.findByUsername(principal.getName());
}
}
以上内容应足以使MyCustomUser可用于所有方法。我想指出的是,您可能需要在这里进行一些错误处理,比如在主体为null时跳过等等,还可以让您的findByUsername
方法返回一个可选值,这样您就可以处理空返回
见:
我必须查看文档以了解它是如何工作的,但我喜欢它。我学会了“春天”的含义。谢谢!关于“如果主体为空,则跳过”,您有什么想法?我如何实现这一点?我尝试使用类似于
@PostMapping(“/signup”)的public void signup(@RequestBody MyCustomUser user)
,但此时主体
为null。在模型属性方法中,我只需在第一行打勾,如果主体==null返回null。在所有端点上,不安全的端点不能自动注入用户,但这是显而易见的。
@ControllerAdvice
public class SomeControllerAdvice {
@Autowired
private MyCustomUserRepository myCustomUserRepository;
@ModelAttribute
public MyCustomUser getUser(Principal principal) {
return myCustomUserRepository.findByUsername(principal.getName());
}
}