使用get将列表或数组传递给RESTeasy



我在各种示例中看到了这种情况,这些示例展示了如何创建一个REST服务,该服务将数组或对象列表作为URL的一部分。

我的问题是,如何使用RESTeasy实现这一点?以下是我认为这是可行的。

   @GET
   @Path("/stuff/")
   @Produces("application/json")
    public StuffResponse getStuffByThings(
            @QueryParam("things") List<Thing> things);

创建一个StringConverter和一个使用包装器对象。这里有一个快速而肮脏的例子:

public class QueryParamAsListTest {
public static class Thing {
    String value;
     Thing(String value){ this.value = value; }
}
public static class ManyThings {
    List<Thing> things = new ArrayList<Thing>();
    ManyThings(String values){
        for(String value : values.split(",")){
            things.add(new Thing(value));
        }
    }
}
static class Converter implements StringConverter<ManyThings> {
    public ManyThings fromString(String str) {
        return new ManyThings(str);
    }
    public String toString(ManyThings value) {
        //TODO: implement
        return value.toString();
    }
}
@Path("/")
public static class Service {
    @GET
    @Path("/stuff/")
    public int getStuffByThings(
        @QueryParam("things") ManyThings things){
        return things.things.size();
    }
}

@Test
public void test() throws Exception {
    Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
    dispatcher.getProviderFactory().addStringConverter(new Converter());
    dispatcher.getRegistry().addSingletonResource(new Service());
    MockHttpRequest request = MockHttpRequest.get("/stuff?things=a,b,c");
    MockHttpResponse response = new MockHttpResponse();
    dispatcher.invoke(request, response);
    Assert.assertEquals("3", response.getContentAsString());

}
}

我认为您还可以使用StringParamUnmarshaller

我很幸运,使用了Collection而不是List。我无法使ListStringConverter工作。

@Provider
public class CollectionConverter implements StringConverter<Collection<String>> {
  public Collection<String> fromString(String string) {
    if (string == null) {
      return Collections.emptyList();
    }
    return Arrays.asList(string.split(","));
  }
  public String toString(Collection<String> values) {
    final StringBuilder sb = new StringBuilder();
    boolean first = true;
    for (String value : values) {
      if (first) {
        first = false;
      } else {
        sb.append(",");
      }
      sb.append(value);
    }
    return sb.toString();
  }
}

我从头开始做toString。一定要编写单元测试以便进行验证。但当然,当你使用番石榴时,一切都会变得更容易、更清晰。可以使用JoinerSplitter。真的很方便。

只需单独使用包装器,不需要其他任何东西。

在您的端点中

@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Path("/find")
@GET
MyResponse find(@QueryParam("ids") Wrapper ids); 

你的包装看起来像这样:

public class Wrapper implements Serializable {
    private List<BigInteger> ids = Collections.emptyList();
    public String toString() {
        return Joiner.on(",")
                     .join(ids);
    }
    public List<BigInteger> get() {
        return ids;
    }
    public Wrapper(String s) {
        if (s == null) {
            ids = Collections.emptyList();
        }
        Iterable<String> splitted = Splitter.on(',')
                                            .split(s);
        Iterable<BigInteger> ids = Iterables.transform(splitted, Functionz.stringToBigInteger);
        this.ids = Lists.newArrayList(ids);
    }
    public Wrapper(List<BigInteger> ids) {
        this.ids = ids;
    }
}

最新更新