我正在尝试在dropwzo资源中实现一个方法,该方法将为来自JS前端(使用DataTable)的调用提供服务。
该请求的查询参数如下所示:
列[0][数据]=0
列[1][数据]=iata
该请求来自用DataTables实现的JS前端,并使用服务器端处理。有关数据表如何在此处发送请求的信息:
https://datatables.net/manual/server-side
我在定义上述查询参数的数据类型时遇到问题。对于Spring数据,我们可以将其定义为:
List<Map<String, String>> columns
它可以包装在一个带有Model At的注释的对象中,它会反序列化很好。
在我的应用程序中,我使用的是依赖于球衣1.19的旧版本的dropw的。我尝试将其注释为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.
}
当我这样做时,我得到:
ERROR[2016-11-07 14:16:13,061]com.sun.jersey.spi.inject.错误:在资源和/或提供程序类中检测到以下错误和警告:严重:缺少方法公共javax.ws.rs.core.响应com.ean.gds.proxy.ams.application.resource.gui.IataMappingGuiResource.get映射(java.util.列表)的依赖项(索引为0)WARN[2016-11-07 14:16:13,070]/:不可用
我的问题是:除了为它编写自定义反序列化程序之外,我还有其他选择吗?
注意:如果我用@Context获取请求,我可以看到decodedQueryParams是一个MultivaluedMap,它将类似“columns[0][data]”的字符串键映射到字符串值列表,这些列表总是有一个元素,即值。
更新:经过一番挖掘,我发现了以下 JAX-RS 规范(第 3.2 节),它解释了为什么我的方法一开始就无效:
支持以下类型:
>
原始类型
具有接受单个 String 参数的构造函数的类型。
具有名为valueOf的静态方法并带有单个字符串参数的类型。
List、Set或SortedSet,其中T满足上面的2或3。
来源:Jersey中处理多个查询参数
所以我试着只用一个列表来代替。这不会使应用程序在启动时崩溃,但是当请求进来时,它会反序列化为一个空列表。所以问题是什么方法是正确的。
事实上,您正在使用的结构与我们为 Rest Web 服务完善映射的所有常见结构非常不同。此外,由于这种结构合规性问题,一旦我们没有传输基于对象的参数,尝试使用 JSON 封送/取消封送值将不适合。
但是,我们有两种选择来“解决这种情况”。让我们看看:
>
采用@QueryParam
策略是不可能的,主要有两个原因:
列表
、集合
等之外,
它的使用有一些限制;
因此,为了获得此要求,您必须制作类似以下内容的内容:
@GET
public Response getMappings(@QueryParam("columns") List<String> columns) {
return Response.status(200).entity(columns).build();
}
// URL to be called (with same param names):
// /mappings?columns=columns[1][name]=0&columns=columns[0][searchable]=false
// Result: [columns[1][name]=0, columns[0][searchable]=false]
您还可以尝试为Param Annotations创建自定义Java类型,如这里所示。这样可以避免编码问题,但在我的测试中,它不适用于括号问题(
您可以使用正则表达式和
@Path
注释来定义 String
参数将接受的内容。不幸的是,您的 URL 将由无效字符(如括号 []
)组成,这意味着您的服务器将返回 500 错误
。
一种替代方法是,如果您将此字符“替换”为有效字符(例如下划线字符,例如):
/mappings/columns_1_=0&columns_1__name_=
这样,可以毫无顾虑地应用解决方案:
@GET
@Path("/{columns: .*}")
public Response getMappings(@PathParam("columns") String columns) {
return Response.status(200).entity(columns).build();
}
// Result: columns_1_=0&columns_1__name_=
执行此操作的更好方法是通过
UriInfo
对象,正如您可能已经尝试过的那样。这更简单,因为无需更改URL和参数。该对象有一个getQueryParameter()
,它返回带有参数值的Map
:
@GET
public Response getMappings(@Context UriInfo uriInfo) {
MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters();
// In case you want to get the whole generated string
String query = uriInfo.getRequestUri().getQuery();
String output = "QueryParams: " + queryParams
+ "<br> Keys: " + queryParams.keySet()
+ "<br> Values: " + queryParams.values()
+ "<br> Query: " + query;
return Response.status(200).entity(output).build();
}
// URL: /mappings?columns[1][name]=0&columns[0][searchable]=false
/* Result:
* QueryParams: {columns[0][searchable]=[false], columns[1][name]=[0]}
* Keys: [columns[0][searchable], columns[1][name]]
* Values: [[false], [0]]
* Query: columns[1][name]=0&columns[0][searchable]=false
*/
但是,您必须意识到,如果您遵循这种方法(使用
Map
),一旦结构不支持它,您就不能拥有重复的键。这就是为什么我包含getQuery()
选项,您可以在其中获取整个字符串。
是否有一种简单的方法来反序列化可以是或
问题内容: 我正在使用Spring的MappingJacksonHttpMessageConverter将JSON消息转换为控制器中的对象。 对于声明为ArrayList的字段,如果json消息包含一个String,则将引发以下异常: 一个例子是下面的类定义: 传入的Json在哪里: 如您所见,这将产生异常,因为图像应该是数组。 我想使自定义解串器更加宽容。如果反序列化失败,则从String中创建
我使用Json-Jackson序列化/反序列化我的对象,并且与内置类配合得很好。 字符串、int等非常好。但是现在我必须序列化/反序列化以特定方式构建的对象。遵循声明: 如果我使用标准的序列化器/反序列化,它会向我显示一条错误消息,例如“java.lang.不支持的操作异常...”,因此它无法序列化/反序列化bobjs。 我如何以一般方式做到这一点,所以我不写3个序列化器/反序列化器,而是只告诉J
问题内容: 我有一个这样的模型: 例如,我从远程获取以下JSON: 当我反序列化此JSON时,and 变量将获得正确的值。但是,我不想解释变量的内容。相反,我希望它是以下字符串: 之后,我将自己解释。我如何获得这个值? 问题答案: Jackson问题596是为原始问题中描述的所需功能而创建的。如果要实施,请投票。 当前可用的解决方案是实现自定义反序列化处理。
问题内容: 从来源来看,我无法影响我在地图中获得的数据,该地图以表示。 我需要处理所包含的数据,最好是(其中的数据非常适合该处理)。 我还需要从数据中生成键列表,因为这些键是事先未知的。 我可以在网上找到的大多数类似问题或多或少都说这是不可能的,但是如果我的地图是,则表明数据在那里,可读性为。 我该怎么办fmt.Println可以做什么? 问题答案: 处理未知接口的一种安全方法,只需使用fmt.S
问题内容: 我想通过Google Gson传输列表对象,但是我不知道如何反序列化泛型类型。 看了这个之后我尝试了什么(BalusC的答案): 但是后来我在日食中遇到了一个错误,说“新的List(){}类型必须实现继承的抽象方法…”,如果我使用快速修复方法,则会得到20个以上的方法存根的怪物。 我很确定有一个更简单的解决方案,但是我似乎找不到它! 编辑: 我现在有 但是,我确实在“ fromJson