我有一个带有 PUT 端点的 Spring Boot RESTful API,可以由不同角色(管理员、主持人等)访问。如何对所有角色使用相同的 DTO
CreateOrUpdateRequest
,但根据用户的角色使用不同的字段验证和序列化规则:
public class CreateOrUpdateRequest {
@NotNull
private String field1;
@NotEmpty
private String field2;
@NotNull
@ValidValueOfEnum(enumClass = MyEnum.class)
private String field3;
}
例如,我希望
ADMIN
角色能够更新所有字段,但MODERATOR
只能更新‘field3’。
我应该为每个角色使用 DTO 吗? 如果是这样,同一个路线和服务方法如何使用多个DTO?
我尝试了
@JsonView
方法,但未序列化的字段将为空。我的 Mapstruct 映射器会将 null 字段映射为 null 并自动清空/删除字段:
@Mapper(componentModel = "spring")
public abstract class RequestMapper {
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_NULL, nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS)
public abstract void update(CreateOrUpdateRequest request, @MappingTarget MyEntity entity);
}
@JsonView
是正确的方法吗?还是有更好的方法在 Spring 中处理这个问题?
假设下面的服务层是通过API访问的,基于用户的所有角色和权限每个字段都可以更新。
@Service
public class EntityService {
@Autowired
private EntityRepository entityRepository;
@Autowired
private UserService userService; // Service to get the currently logged-in user
public void updateEntity(Long entityId, Map<String, Object> updates) {
// Get the current user
User currentUser = userService.getCurrentUser();
Role userRole = currentUser.getRole();
// Fetch the entity from the database
Entity entity = entityRepository.findById(entityId)
.orElseThrow(() -> new EntityNotFoundException("Entity not found"));
// Perform field-level checks
if (userRole == Role.USER_A) {
if (updates.containsKey("field2")) {
throw new AccessDeniedException("User A cannot update field2");
}
// Update field1
entity.setField1((String) updates.get("field1"));
} else if (userRole == Role.USER_B) {
if (updates.containsKey("field1")) {
throw new AccessDeniedException("User B cannot update field1");
}
// Update field2
entity.setField2((String) updates.get("field2"));
} else {
throw new AccessDeniedException("Unknown role");
}
// Save the updated entity
entityRepository.save(entity);
}
}