当前位置: 首页 > 知识库问答 >
问题:

反序列化球衣1中的List<Map<String,String>>QueryParam

韩梓
2023-03-14

我正在尝试在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中处理多个查询参数

    所以我试着只用一个列表来代替。这不会使应用程序在启动时崩溃,但是当请求进来时,它会反序列化为一个空列表。所以问题是什么方法是正确的。

  • 共有1个答案

    裴展
    2023-03-14

    事实上,您正在使用的结构与我们为 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