Согласно документации Play 2.7 Java, если вы хотите отобразить параметр строки запроса (например, идентификатор пользователя) на бизнес-объект из базы данных: «Поэтому вы, например, будете использовать простой идентификатор объекта в качестве привязываемого пути и извлекать реальноезначения с использованием композиции действий. "
см. https://www.playframework.com/documentation/2.7.x/RequestBinders
Моя цель - централизовать загрузку пользователя из базы данных, поскольку он используется в нескольких методах. Таким образом, в каждом методе контроллера у меня уже был бы пользовательский объект в качестве аргумента метода вместо параметра запроса userId.
Я попытался использовать класс «UserBindable», реализующий интерфейс PathBindable, и сконфигурировать его в conf / routeсоответственно. Это успешно сопоставляет параметр запроса с объектом PathBindable, и я могу получить к нему доступ внутри метода контроллера. Но, как предполагает документ Play, я не хочу, чтобы какой-либо доступ к БД внутри метода привязки PathBindable оставался неблокирующим.
Я пытался внедрить PathBindable в своем действии, но это приводит к нулевому значению.
Вместо (без привязки пути / композиции действия):
public class UserController extends Controller {
// Return all pets from the user
public Result pets(Http.Request request, String userId) {
Optional<DbUser> user = dataAccess.loadUser(userId);
if(user.isPresent()){
List<Pet> pets = dataAccess.loadPetsFor(user);
return ok(views.html.pets.render(user, pets));
} else {
return notFound("User not found");
}
}
// more methods working with the user object
}
IСтремление к:
public class LoadUser extends Action.Simple {
public CompletionStage<Result> call(Http.Request r) {
Optional<DbUser> user = dataAccess.loadUser(userId); // how to get this id???
if(user.isPresent()) {
return delegate.call(r.addAttr(Attrs.USER, user));
} else {
return CompletableFuture.completableFuture(notFound("User not found"));
}
}
}
-----
public class UserBindable implements PathBindable<UserBindable> {
String userId;
// empty constructor
// constructor taking the userId as argument
@Override
public UserBindable bind(String key, String userId){
return new UserBindable(userId);
}
// other methods omitted
}
-----
With(LoadUser.class)
public class UserController extends Controller {
// Return all pets from the user routes: /user/:userId/pets
public Result pets(Http.Request r, UserBindable userBindable) {
User user = r.attrs().get(Attrs.USER);
List<Pet> pets = dataAccess.loadPetsFor(user);
return ok(views.html.pets.render(user, pets));
}
}
Если мой подход верен, как получить доступ к параметру запроса в Action или как получить доступ к PathBindable? Если мой подход неверен, что лучше?
Большое спасибо!