【发布时间】:2016-11-07 14:22:39
【问题描述】:
我正在尝试在 dropwizard 资源中实现一个方法,该方法将为来自 JS 前端(使用 DataTables)的调用提供服务。
请求具有如下所示的查询参数:
columns[0][data]=0&columns[0][name]=&columns[0][searchable]=false&columns[0][orderable]=false&columns[0][search][value]=&columns[0] [搜索][正则表达式]=false
columns[1][data]=iata&columns[1][name]=iata&columns[1][searchable]=true&columns[1][orderable]=true&columns[1][search][value]=&columns[1] [搜索][正则表达式]=false
请求来自一个用 DataTables 实现的 JS 前端,并使用服务器端处理。有关数据表如何在此处发送请求的信息:
https://datatables.net/manual/server-side
我在为上述查询参数定义数据类型时遇到问题。有了spring data,我们可以定义为:
List<Map<String, String>> columns
它可以被包裹在一个用 ModelAttribute 注释的对象中,它会很好地反序列化。
在我的应用中,我使用的是旧版本的 dropwizard,它依赖于 jersey 1.19。 我尝试将其注释为 QueryParam,但应用程序在启动时失败。
方法:
@Path("/mappings")
@GET
@Timed
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response getMappings(@QueryParam("columns") List<Map<String, String>> columns) {
// processing here.
}
当我这样做时,我得到:
错误 [2016-11-07 14:16:13,061] com.sun.jersey.spi.inject.Errors: 使用资源和/或检测到以下错误和警告 提供者类:严重:缺少公共方法的依赖项 javax.ws.rs.core.Response com.ean.gds.proxy.ams.application.resource.gui.IataMappingGuiResource.getMappings(java.util.List) at 索引 0 处的参数 WARN [2016-11-07 14:16:13,070] /: 不可用
我的问题是:除了为它编写自定义反序列化器之外,我还有其他选择吗?
注意:如果我使用@Context 获取请求,我可以看到解码的QueryParams 是一个MultivaluedMap,它将诸如“columns[0][data]”之类的字符串键映射到字符串值列表,该列表始终具有单个元素,这就是价值。
更新: 经过一番挖掘,我发现了以下 JAX-RS 规范(第 3.2 节),它解释了为什么我的方法一开始就无效:
支持以下类型:
原始类型
具有接受单个字符串参数的构造函数的类型。
具有名为 valueOf 的静态方法和单个 String 参数的类型。
List、Set 或 SortedSet,其中 T 满足上述 2 或 3。
来源:Handling Multiple Query Parameters in Jersey
所以我尝试只使用一个列表。这不会在启动时使应用程序崩溃,但是当请求进来时,它会反序列化为一个空列表。所以问题仍然是什么方法是正确的。
【问题讨论】:
-
这是您必须手动解析的内容。或者找一个知道如何解析它的库。泽西在这方面不够聪明
-
这个客户端库不允许您以 JSON 格式发送数据吗?如果您需要坚持查询参数而不是在正文中发送它,您仍然可以更轻松地解析 JSON,然后您就可以使用当前格式。我知道大多数 JS 数据表库都允许 JSON 格式
-
@peeskillet 不幸的是它没有。我无法控制图书馆如何在请求中发送这些数据。我目前正在使用自定义解析器。谢谢!
标签: java datatables jersey dropwizard