【问题标题】:Passing a list or array to RESTeasy using get使用 get 将列表或数组传递给 RESTeasy
【发布时间】:2012-01-14 04:58:53
【问题描述】:
我已经在各种示例中看到过这样的事情,这些示例展示了如何创建一个 REST 服务,该服务将数组或对象列表作为 URL 的一部分。
我的问题是,如何使用 RESTeasy 实现这一点?
像下面这样的东西就是我认为这是如何工作的。
@GET
@Path("/stuff/")
@Produces("application/json")
public StuffResponse getStuffByThings(
@QueryParam("things") List<Thing> things);
【问题讨论】:
标签:
arrays
rest
get
resteasy
【解决方案1】:
创建一个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
【解决方案2】:
我很幸运,使用Collection 而不是List。我无法为List 工作创建StringConverter。
@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。请务必编写单元测试以对其进行验证。但是,当然,当您使用 Guava 时,一切都会变得更容易、更清晰。可以使用Joiner 和Splitter。真的很方便。
【解决方案3】:
只需要自己使用一个包装器,不需要其他任何东西。
在你的端点中
@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;
}
}