Как использовать PathBindable и Action Composition для загрузки объектов БД в Play 2.7 - PullRequest
0 голосов
/ 01 октября 2019

Согласно документации 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? Если мой подход неверен, что лучше?

Большое спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...