I have a problem with java reflection. I use org.springframework.util.ReflectionUtils on my User class to "trim" white spaces from String attributes (let's not question my good practices now :).
The problem is, the attributes being private, that the reflection works in my DataLoader class but throws an exception when used in rest controller, which I think should be the right behavior. How come it works in the first example?
java.lang.IllegalStateException: Not allowed to access field 'username': java.lang.IllegalAccessException: Class TrimListener can not access a member of class User with modifiers "private"
User class
@Entity
@EntityListeners(TrimListener.class)
@Getter @Setter @NoArgsConstructor @AllArgsConstructor
public class User extends DatabaseObject {
private String username;
}
TrimListener class
public class TrimListener<T extends DatabaseObject> {
@PreUpdate
@PrePersist
public void trim (T object) {
ReflectionUtils.doWithFields(object.getClass(), field -> {
if(field.get(object) != null) {
if(!field.get(object).toString().equals(field.get(object).toString().trim())) {
field.set(object, field.get(object).toString().trim());
}
}
}, new TrimmableFieldFilter());
}
private class TrimmableFieldFilter implements ReflectionUtils.FieldFilter {
@Override
public boolean matches(Field field) {
return (field.getType().equals(String.class));
}
}
DataLoader singleton, used to load sample data into DB. Here, the TrimmerListener works as it should, trimming username.
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
public class DataLoader {
@PostConstruct
public void loadData() {
User user = new User("vladko ");
userRepo.save(user);
}
}
Rest controller, which should just persist user. This version causes exception to be thrown, because accessing the private field of User through org.springframework.util.ReflectionUtils
@RestController
@RequestMapping("/user")
public class UserController extends DatabaseObjectController<User> {
@PostMapping("/create")
public ResponseEntity<UserDTO> createUser(@RequestBody(required = true) User user) {
userRepo.save(user);
return ResponseEntity.ok().body(user.toDTO());
}
}
Thank you.
Aucun commentaire:
Enregistrer un commentaire