为啥从 AOP 传递到具有其他参数的控制器的模型的所有属性都是空的
Posted
技术标签:
【中文标题】为啥从 AOP 传递到具有其他参数的控制器的模型的所有属性都是空的【英文标题】:Why all properties of a Model passed from AOP to controller with other arguments are null为什么从 AOP 传递到具有其他参数的控制器的模型的所有属性都是空的 【发布时间】:2020-12-28 14:37:01 【问题描述】:AOP
@Around(
"execution(* net.inter.warp.bridge.controller.*.*(.., net.inter.warp.bridge.model.User)) && " +
"args(.., authenticatedUser)"
)
public Object withAuthenticatedUser(ProceedingJoinPoint joinPoint, User authenticatedUser) throws Throwable
System.out.println(joinPoint + " -> " + authenticatedUser);
User user = null;
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null)
user = (User) userService.loadUserByUsername(authentication.getName());
else
throw new UnauthorizedException("err 1");
if (user == null)
throw new UnauthorizedException("err 2");
return joinPoint.proceed(new Object[]user);
控制器(authenticatedUser 的所有属性都为空)
package net.inter.warp.bridge.controller;
@GetMapping("/boxes/id")
public ResponseEntity<Box> getBoxById(@PathVariable(value = "id") Long boxId, User authenticatedUser)
throws NoDynamicTableFoundException, ResourceNotFoundException
控制器(这是因为除了authenticatedUser之外没有更多参数了)
package net.inter.warp.bridge.controller;
@GetMapping("/boxes/id")
public ResponseEntity<Box> getBoxById(User authenticatedUser)
throws NoDynamicTableFoundException, ResourceNotFoundException
AOP 似乎讨厌其他参数... authenticatedUser 不为 null,authenticatedUser 的每个属性都为 null。
模型(我不确定这个问题是否与此有关)
@Entity
@Table(name="users")
@ToString
public class User extends AuthEntity implements UserDetails
@Override
public Collection<? extends GrantedAuthority> getAuthorities()
String[] userRoles = this.roles.stream().map((role) -> role.getName()).toArray(String[]::new);
Collection<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList(userRoles);
return authorities;
@Override
public String getUsername()
return this.email;
@Override
public boolean isAccountNonExpired()
return true;
@Override
public boolean isAccountNonLocked()
return true;
@Override
public boolean isCredentialsNonExpired()
return true;
@Override
public boolean isEnabled()
return true;
@Column(nullable=false)
@NotNull(message = "")
private String name;
@Column(nullable=false, unique=true)
@Email
//@NotBlank(message = "")
private String email;
@Column
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
@JsonIgnore
private String password;
@Column(length = 20, columnDefinition ="bigint")
//@NotNull(message = "")
private Long organization_id;
@ManyToOne(optional=false)
@JoinColumn(name = "organization_id",referencedColumnName="id", insertable=false, updatable=false)
//@JsonIgnore
private Organization organization;
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
//@Fetch(org.hibernate.annotations.FetchMode.SELECT)
@JoinTable(
name="user_role",
joinColumns=@JoinColumn(name="user_id"),
inverseJoinColumns=@JoinColumn(name="role_id"))
private List<Role> roles;
/*
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
//@Fetch(org.hibernate.annotations.FetchMode.SELECT)
@Fetch(value = FetchMode.SUBSELECT)
@JoinTable(
name="hyperbridge_resource.user_workspace",
joinColumns=@JoinColumn(name="user_id"),
inverseJoinColumns=@JoinColumn(name="workspace_id"))
private List<Workspace> workspaces;
*/
@Column(length = 1, columnDefinition ="char")
private String active;
@Column(name = "reset_token")
@JsonIgnore
private String resetToken;
@Column(name = "reset_token_time")
@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss", timezone = "Asia/Seoul")
private LocalDateTime resetTokenTime;
public String getName()
return name;
public void setName(String name)
this.name = name;
public String getEmail()
return email;
public void setEmail(String email)
this.email = email;
public String getPassword()
return password;
public void setPassword(String password)
this.password = password;
public Long getOrganization_id()
return organization_id;
public void setOrganization_id(Long organization_id)
this.organization_id = organization_id;
public Organization getOrganization()
return organization;
public void setOrganization(Organization organization)
this.organization = organization;
public List<Role> getRoles()
return roles;
public void setRoles(List<Role> roles)
this.roles = roles;
/* public List<Workspace> getWorkspaces()
return workspaces;
public void setWorkspaces(List<Workspace> workspaces)
this.workspaces = workspaces;
*/
public String getActive()
return active;
public void setActive(String active)
this.active = active;
public String getResetToken()
return resetToken;
public void setResetToken(String resetToken)
this.resetToken = resetToken;
public LocalDateTime getResetTokenTime()
return resetTokenTime;
public void setResetTokenTime(LocalDateTime resetTokenTime)
this.resetTokenTime = resetTokenTime;
【问题讨论】:
放弃你的方面,因为它破坏了正确调用该方法,并且 Spring Security 已经支持这种开箱即用的方法,你不需要 AOP。在你的方法参数上使用@AuthenticationPrincipal
。
我只能通过@AuthenticationPrincipal 获取用户名、密码、启用等,但我的用户对象中还有其他参数位于模型文件夹中。
如果您使用自己的 User
对象,您就不必使用 Spring Security User
对象。
我知道有很多方法但不希望控制器冗余,所以最终选择了这个-***.com/a/41327161/7344596
@GetMapping("/binders") public Page试试这个,doc:
@Around(
"execution(* net.inter.warp.bridge.controller.*.*(..) && " +
"args(authenticatedUser,..)"
【讨论】:
以上是关于为啥从 AOP 传递到具有其他参数的控制器的模型的所有属性都是空的的主要内容,如果未能解决你的问题,请参考以下文章