Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Jackson ObjectMapper-指定对象属性的序列化顺序_Java_Json_Serialization_Jackson - Fatal编程技术网

Java Jackson ObjectMapper-指定对象属性的序列化顺序

Java Jackson ObjectMapper-指定对象属性的序列化顺序,java,json,serialization,jackson,Java,Json,Serialization,Jackson,我正在实现一个RESTful web服务,其中用户必须随请求一起发送一个签名的验证令牌,这样我就可以确保请求没有被中间人篡改。我当前的实现如下 验证令牌是一个VerifData对象,序列化为字符串,然后进行哈希和加密 class VerifData { int prop1; int prop2; } 在我的服务中,我将要序列化的数据放入VerifData实例中,然后使用Jackson ObjectMapper对其进行序列化,并将其与验证令牌一起传递给验证引擎 VerfiData

我正在实现一个RESTful web服务,其中用户必须随请求一起发送一个签名的验证令牌,这样我就可以确保请求没有被中间人篡改。我当前的实现如下

验证令牌是一个VerifData对象,序列化为字符串,然后进行哈希和加密

class VerifData {
    int prop1;
    int prop2;
}
在我的服务中,我将要序列化的数据放入VerifData实例中,然后使用Jackson ObjectMapper对其进行序列化,并将其与验证令牌一起传递给验证引擎

VerfiData verifData = new VerifData(12345, 67890);
ObjectMapper mapper = new ObjectMapper();
String verifCodeGenerated = mapper.writeValueAsString(verifData);
但似乎每次启动应用程序容器时,ObjectMapper映射到字符串的属性顺序都会发生变化

有一次是这样

{"prop1":12345,"prop2":67890}
{"prop2":67890,"prop1":12345}
还有一次会是

{"prop1":12345,"prop2":67890}
{"prop2":67890,"prop1":12345}
因此,如果客户端已将VerifData实例序列化为第一个字符串,则即使它是正确的,也有50%的几率失败

有没有办法绕过这个问题?我是否可以指定ObjectMapper映射属性的顺序(如升序)?或者是否有任何其他方法可以最好地实施此验证步骤。客户端和服务器实现都是由我开发的。我使用Java安全API进行签名和验证。

来自:


注释是有用的,但在任何地方应用都会很麻烦。您可以将整个
ObjectMapper
配置为以这种方式使用

当前版本:

objectMapper.configure(MapperFeature.SORT\u PROPERTIES\u字母顺序,true)

旧版本的杰克逊:


objectMapper.configure(SerializationConfig.Feature.SORT_PROPERTIES_字母顺序,true)

来自邓肯·麦格雷戈的回答: 最好是这样使用:

objectMapper.configure(SerializationConfig.Feature.SORT_PROPERTIES_ALPHABETICALLY, true);

由于MapperFeature适用于XMLs,并且附带jackson databind,这是不需要的…

在Spring Boot中,您可以通过将以下内容添加到
应用程序的入口点类来全局添加此行为:

  @Bean
  public Jackson2ObjectMapperBuilder objectMapperBuilder() {

    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
    builder.featuresToEnable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY);

    return builder;
  }

通过指定属性(在
application.properties
中,例如:

spring.jackson.mapper.sort_properties_alphabetically=true

在您今天可能正在使用的Jackson 2.x中,请使用:

ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);

如果你关心外观,你也可以考虑<代码>序列化特性。 请注意,必须序列化映射或对象才能正确排序。例如,如果序列化

JsonNode
(从
readTree
),则不会正确缩进

例子 结果:

{
  "hello" : {
    "cruel" : "world"
  }
}

不使用标志参数:

objectMapper.enable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY);

需要以下2ObjectMapper配置:

ObjectMapper.configure(MapperFeature.SORT\u PROPERTIES\u字母顺序,true)


ObjectMapper.enable(MapperFeature.SORT\u PROPERTIES\u按字母顺序)

定义用于POJO字段的属性序列化顺序
注意:是否适用于
java.util.Map
序列化


ObjectMapper.configure(SerializationFeature.ORDER\u MAP\u ENTRIES\u BY\u key,true)


ObjectMapper.enable(序列化功能。按键排序映射条目)

确定在序列化之前是否先按键对
java.util.Map
项进行排序的功能


Spring启动配置示例(yaml):

spring:
杰克逊:
制图员:
按字母顺序对属性进行排序:true
序列化:
按键排序映射条目:true

您可以使用mix-in并根据需要指定属性的顺序:

import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.databind.ObjectMapper;

import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public final class ObjectMapperUtils {

    private static final ObjectMapper MAPPER = new ObjectMapper();

    static {
        MAPPER.addMixIn(Object.class, IdFirst.class);
    }

    @Bean
    public ObjectMapper objectMapper() {
        return MAPPER;
    }

    @JsonPropertyOrder({"id", "...", "..."})
    private abstract static class IdFirst {}

}

我意识到这是一条老线索,但由于我正在寻找答案并在这里登陆,一些额外的信息可能对其他人很方便。

我当前使用的@JsonProperty注释(jackson-annotations-2.11.2)除了接受“value”参数外,还接受一个“index”(数字)参数,指定序列化过程中字段的顺序。

我今天发现了另一种方法,以防字母顺序不是您所需的排序顺序。结果表明,在字段上添加@JsonProperty注释时,如果其余字段未注释,则会在写入时将其放在最后。我发现,当我要指定属性时不符合java命名约定的y名称

通过添加索引属性,您可以定义顺序。最低索引放在第一位

@JsonProperty(index=20)
String prop1;

@JsonProperty(index=10)
String prop2;
将导致:

{"prop2": "valueProp2", "prop1": "valueProp1"}

从下面提到的链接“所有codehaus服务都已终止”,如果您的目标是在任何地方应用排序,而不是在序列化特定对象时,请参见。这并不完全正确(或者至少不适用于所有场景)--请参阅,以获得一个有效的完整示例。@user2089674-您的示例仅适用于映射键。OP请求了对象字段的解决方案。只有一个映射项。因此,我看不到它的顺序。