Вызвать метод подресурса в подзапросе? - PullRequest
3 голосов
/ 06 марта 2012

У меня есть ресурс, производящий JSON, который возвращает ссылки на несколько дочерних ресурсов (которые также создают JSON). Этот ресурс может быть включен из нескольких разных точек дерева, поэтому оба используют absolutePathBuilder для создания ссылок на дочерние ресурсы.

public class AResource {
    @GET
    @Produces(MediaType.APPLICATION_JSON + ";charset=utf8")
    public Map<String, Object> getRoot(@Context final UriInfo info) {
        final Map<String, Object> toReturn = new HashMap<String, Object>();
        final String[] children = { "one", "two", "thrée" };
        final UriBuilder builder = info.getAbsolutePathBuilder().path("{child}");
        for (final String child : children) {
            toReturn.put(child, builder.build(child).toASCIIString());
        }
        return toReturn;
    }

    @Path("{child:(one|two|thrée)}")
    public ChildResource getChild(@PathParam("child") final String child) {
        return new ChildResource("AResource " + child);
    }
}
public class ChildResource {
    public Map<String, Object> getRoot(@Context final UriInfo info) {
        ...
    }
}

Теперь допустим, что мне нужно добавить еще один MediaType, QueryParam и т. Д., Что приведет к тому, что родительский ресурс вернет существующий JSON с возвратом каждого из дочерних ресурсов внутри него.

Есть ли в JAX-RS или Джерси способ легко создать / внедрить измененный контекст в подресурс? Или сделать подзапрос внутри контейнера?

В настоящее время я работаю с наивным решением, в котором я беру карту у дочернего элемента, а затем обрабатываю ее, чтобы обновить любой URI, укоренившийся в текущем пути, но создается впечатление, что должно быть лучшее решение (которое не не требует повторного хэширования карты после факта?)

1 Ответ

0 голосов
/ 07 марта 2012

Не то чтобы я знал.По крайней мере, не так, как настроен ваш текущий метод.

Вот способ получить такую ​​функциональность, но для этого потребуется другая архитектура вашего кода ...

1) Используйте Response иКлассы ResponseBuilder, чтобы обернуть ваши объекты.Это не только позволит вам настраивать статус ответа, но вы также можете позволить одному методу отвечать на QueryParams и настраивать сущность, которую вы доставляете, что приводит к ...

2) Если вам нужно доставитьнесколько версий ваших сущностей затем создайте для них Фасады.По сути, просто создайте классы, которые содержат структуру того, как вы хотели бы, чтобы ваши ответы JSON выглядели.В вашем случае один будет представлять дочерние ресурсы как строки URL, а другой просто будет содержать дочерние объекты.

public class ParentResource{
  @GET
  @Produces("application/json")
  public Response getParent(
    @Context UriInfo uriInfo
    , @DefaultValue("false") @QueryParam("cascade") Boolean cascade 
  ) {
    if(cascade)
      //This assumes that your ParentEntity stores the child objects already.
      return Response.ok().entity(new ParentEntity).build();
    else
      return Response.ok().entity(new ParentFacadeWithURLS(uriInfo)).build();
  }
}

РЕДАКТИРОВАТЬ # 1 2012.03.07

public class AResource {
    @GET
    @Produces("application/json")
    public Map<String, Object> getRoot(
      @Context final UriInfo info
      , @DefaultValue("false") @QueryParam("cascade") Boolean cascade
    ) {
      final Map<String, Object> toReturn = new HashMap<String, Object>();
      final String[] children = { "one", "two", "thrée" };
      if(cascade){
        ChildResource cr= new ChildResource();
        toReturn.put(child, cr.getRoot(uriInfo));
      } else {
        final UriBuilder builder = info.getAbsolutePathBuilder().path("{child}");
        for (final String child : children) {
            toReturn.put(child, builder.build(child).toASCIIString());
        }
      }
      return toReturn;
    }

    @GET
    @Path("{child:(one|two|thrée)}")
    public ChildResource getChild(@PathParam("child") final String child) {
        ChildResource cr = new ChildResource();
        return new cr.getRoot(child);
    }
}
...