我正在使用带有 Java 11 的 Spring Boot 2.1。我已经用 fastxml 注释对我的用户模型进行了注释,以便我的密码可以被 POST 请求接受,但不能被其他 REST 请求返回......
@Data
@Entity
@Table(name = "Users")
public class User implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private UUID id;
private String firstName;
private String lastName;
@NotBlank(message = "Email is mandatory")
@Column(unique=true)
private String email;
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String password;
private boolean enabled;
private boolean tokenExpired;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(
name = "users_roles",
joinColumns = @JoinColumn(
name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(
name = "role_id", referencedColumnName = "id"))
private Collection<Role> roles;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getUsername() {
return email;
}
@Override
public boolean isAccountNonExpired() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isAccountNonLocked() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return false;
}
@PrePersist @PreUpdate
private void prepare(){
this.email = this.email.toLowerCase();
}
}
但是,在尝试运行集成测试时,“objectMapper.writeValueAsString”不会翻译密码。这是我的测试...
@SpringBootTest(classes = CardmaniaApplication.class,
webEnvironment = WebEnvironment.RANDOM_PORT)
public class UserControllerIntegrationTest {
@Autowired
private TestRestTemplate restTemplate;
@Autowired
private ObjectMapper objectMapper;
@Autowired
private IUserRepository userRepository;
@Test
@WithUserDetails("me@example.com")
void registrationWorksThroughAllLayers() throws Exception {
final String email = "newuser@test.com";
final String firstName = "first";
final String lastName = "last";
final String password = "password";
User user = getTestUser(email, password, firstName, lastName, Name.USER);
ResponseEntity<String> responseEntity = this.restTemplate
.postForEntity("http://localhost:" + port + "/api/users", user, String.class);
assertEquals(201, responseEntity.getStatusCodeValue());
final User createdUser = userRepository.findByEmail(email);
assertNotNull(createdUser);
assertNotNull(createdUser.getPassword());
}
@Test
@WithUserDetails("me@example.com")
void getDetailsAboutMyself() throws JsonProcessingException, JSONException {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
UserDetails user = (UserDetails) authentication.getPrincipal();
final User foundUser = userRepository.findByEmail(user.getUsername());
ResponseEntity<String> responseEntity = this.restTemplate
.getForEntity("http://localhost:" + port + "/api/users/" + foundUser.getId(), String.class);
assertEquals(200, responseEntity.getStatusCodeValue());
// assert proper response
final String userAsJson = objectMapper.writeValueAsString(user);
assertEquals(userAsJson, responseEntity.getBody());
JSONObject object = (JSONObject) new JSONTokener(userAsJson).nextValue();
// Verify no password is returned.
assertNull(object.getString("password"));
}
...
}
objectMapper.writeValueAsString 调用中的 JSON 是
{"id":null,"firstName":"first","lastName":"last","email":"newuser@test.com","enabled":true,"tokenExpired":false,"roles":null,"username":"newuser@test.com","authorities":null,"accountNonExpired":false,"accountNonLocked":false,"credentialsNonExpired":false}
在从读取端点请求我的实体时,将我的密码包含在映射中以及抑制密码的正确方法是什么?