Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将主体作为控制器中的方法参数绑定到MyCustomUser类_Java_Spring_Spring Boot - Fatal编程技术网

Java 将主体作为控制器中的方法参数绑定到MyCustomUser类

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

我知道您可以在Spring控制器中轻松获得用户名,方法参数包括
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());
  }
}