我正在开发一个测试DropWizard网络服务,用作电话簿(基于this Packt Publishing book。
我有一个ContactResource类,其中包含索引联系人的标准路由:
@Path("/contacts")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class ContactResource {
private final ContactDao contactDao;
public ContactResource(DBI jdbi) {
contactDao = jdbi.onDemand(ContactDao.class);
}
@GET
public Response indexContacts(@QueryParam("ids") Optional<List<Integer>> ids) {
List<Contact> contacts;
contacts = contactDao.indexContacts(ids);
return Response.status(Response.Status.OK).entity(contacts).build();
}
}
如上面的代码所示,我希望索引操作可选按id过滤结果(发送id列表时)。如果我没有发送ids
参数,我希望获得所有联系人。
不幸的是,该服务拒绝启动以下错误:
[[FATAL] No injection source found for a parameter of type public javax.ws.rs.core.Response com.dwbook.phonebook.resources.ContactResource.indexContacts(com.google.common.base.Optional) at index 0.
如果我删除Optional<>
位并重构contactDao方法,则路由有效。但重点是允许可选的过滤。
如何在DropWizard中定义Optional<List<T>>
参数?
提前致谢!
编辑:根据condit的回答,我以这种方式重构了行动:
@GET
public Response indexContacts(@QueryParam("ids") List<Integer> ids) {
List<Contact> contacts;
if(ids.isEmpty()) {
contacts = contactDao.indexContacts();
} else {
contacts = contactDao.filterContactsByIds(ids);
}
return Response.status(Response.Status.OK).entity(contacts).build();
}
这很有效,但我可以看到这很快失控,以防我必须实现多个过滤器(例如,可选择按firstName,lastName或国籍过滤联系人)。
一般来说,在Dropwizard / JDBI中实现任意数量的可选过滤器的首选方法是什么?
答案 0 :(得分:1)
Jersey不知道如何处理Optional
参数。它只处理default entity types,除非其他人已注册。
在这种情况下,我认为您甚至不需要Optional
,因为您可以使用List
免费获得此内容。如果没有指定ids
查询参数,则Jersey将生成空List
,您可以使用ids.isEmpty()
来测试是否需要进行任何过滤。