Аннотация @BeanParam в GUICE + JERSEY Bridge

    @GET
    @Path("/book")
    public Response getBook(@BeanParam Filter filter) {

    }

Параметр фильтра инициализируется, но в компоненте ничего не установлено

class Filter {@QueryParam("author")String author}

У меня есть сеттер и геттер для всех свойств, присутствующих в объекте фильтра.

F.Y.I. Я использую HK2 guice-bridge.


person pinakin    schedule 30.04.2017    source источник
comment
Что должен представлять author? @FormParam, @QueryParam, @HeaderParam и т. д.? Вы добавили аннотацию соответственно?   -  person Paul Samsotha    schedule 30.04.2017
comment
Да, я добавил аннотацию, это QueryParam обновил вопрос.   -  person pinakin    schedule 30.04.2017
comment
То есть вы говорите, что это работает без подсказки, и проблема в этой подсказке? Можете ли вы подтвердить это. Просто пытаюсь понять, почему вы вообще упоминаете guice.   -  person Paul Samsotha    schedule 30.04.2017
comment
проверьте это github.com/medvedev/beanparam-jersey-guice у кого-то есть образец проект, чтобы показать проблему с фреймворком Jersey @BeanParam и Guice DI.   -  person pinakin    schedule 30.04.2017
comment
Я не использую библиотеку (dropwizard-guice), которую вы используете, но выглядит открытая проблема   -  person Paul Samsotha    schedule 30.04.2017
comment
Я не использую dropwizard-guice. Я просто использую hk2.java.net/guice-bridge. Есть ли другой способ заставить Гайса и Джерси работать вместе? Кажется, есть много проблем с Guice и Jersey 2.X.   -  person pinakin    schedule 30.04.2017
comment
Это можно сделать без моста, вы можете создать экземпляр класса с помощью Guice и зарегистрировать его в контексте Джерси. Или вы можете использовать модуль Guice Webserver, который работает именно так: github.com/sorskod/webserver   -  person sasa    schedule 26.08.2017


Ответы (2)


Я смог воспроизвести проблему с guice-bridge. Кажется, что когда мост инициализируется (через guiceBridge.bridgeGuiceInjector(...)), вызывается только конструктор BeanParam по умолчанию вместо установки свойств (или вызова конструктора с параметрами).

Если это возможно в вашем проекте, вы можете попытаться предоставить конструктору параметры.

Это простое приложение:

public class App extends ResourceConfig {

   @Inject
   public App(final ServiceLocator serviceLocator) {
     register(Service.class);

     final Injector injector = initializeInjector(serviceLocator);
   }

   private Injector initializeInjector(final ServiceLocator serviceLocator) {
     GuiceBridge.getGuiceBridge()
         .initializeGuiceBridge(serviceLocator);

     final Injector injector = Guice.createInjector(
         new ApplicationModule(serviceLocator));
     final GuiceIntoHK2Bridge guiceBridge = serviceLocator.getService(GuiceIntoHK2Bridge.class);
     guiceBridge.bridgeGuiceInjector(injector);
     return injector;
   }

}

Используемый сервис:

@Path("service")
public class Service {

  @POST
  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
  public Response save(@Valid @BeanParam final SimpleBean bean) {
    System.out.println(bean.getProperty());
    return Response.status(Status.CREATED)
        .build();
  }
}

А вот простой боб:

public class SimpleBean {

  // Avoid this constructor!
  // public SimpleBean() {
  //  System.out.println("constructor called");
  // }

  public SimpleBean(@FormParam("property") final String property) {
    this.property = property;
    System.out.println("constructor with params called: " + property);
  }

  @Length(max = 100)
  @NotBlank
  private String property;

  public String getProperty() {
    System.out.println("getter called");
    return property;
  }

  public void setProperty(final String property) {
    System.out.println("setter called with " + property);
    this.property = property;
  }

}

Использование Guice версии 4.1.0, guice-bridge версии 2.4.0, Jersey версии 2.25.1 и сервлета Javax версии 3.1.0.

person Lukas S.    schedule 20.06.2017

Вы можете попробовать использовать Guice-Jersey без бриджа. Существует проект под названием "Модуль веб-сервера Guice", который интегрирует Guice с Jersey 2, Jetty и Jackson, где это подход реализуется.

Что вам нужно сделать, так это связать свой ресурс в контексте Guice, например.

public class MyModule extends AbstractModule() {
    public void configure() {
            bind(BooksResource.class);
    }

Существует функция Джерси, которая сканирует все привязки, аннотированные с помощью @Path, и регистрирует экземпляр в контексте Джерси после создания экземпляра:

public boolean configure(FeatureContext context) {
    injector.getBindings().entrySet()
        .stream()
        .filter(entry -> entry.getKey().getTypeLiteral().getRawType().getAnnotation(Path.class) != null)
        .map(entry -> injector.getInstance(entry.getKey()))
        .forEach(context::register);

    return true;
  }

Также есть пример (написанный как часть интеграционного теста) для BeanParams — BeanParamsIntegrationTest

person sasa    schedule 25.08.2017