java spring MappingJacksonJsonView未在mongodb ObjectId上执行字符串

java spring MappingJacksonJsonView未在mongodb ObjectId上执行字符串,java,json,spring,mongodb,jackson,Java,Json,Spring,Mongodb,Jackson,我在SpringMVC应用程序中使用MappingJacksonJsonView从控制器呈现JSON。我希望对象中的ObjectId呈现为.toString,但它将ObjectId序列化为各个部分。它在我的Velocity/JSP页面中运行良好: Velocity: $thing.id Produces: 4f1d77bb3a13870ff0783c25 Json: <script type="text/javascript"> $.aj

我在SpringMVC应用程序中使用MappingJacksonJsonView从控制器呈现JSON。我希望对象中的ObjectId呈现为.toString,但它将ObjectId序列化为各个部分。它在我的Velocity/JSP页面中运行良好:

Velocity:
    $thing.id
Produces:
    4f1d77bb3a13870ff0783c25


Json:
    <script type="text/javascript">
         $.ajax({
             type: 'GET',
             url: '/things/show/4f1d77bb3a13870ff0783c25',
             dataType: 'json',
             success : function(data) {
                alert(data);
             }
         });
    </script>
Produces:
    thing: {id:{time:1327331259000, new:false, machine:974358287, timeSecond:1327331259, inc:-260555739},…}
        id: {time:1327331259000, new:false, machine:974358287, timeSecond:1327331259, inc:-260555739}
            inc: -260555739
            machine: 974358287
            new: false
            time: 1327331259000
            timeSecond: 1327331259
        name: "Stack Overflow"


XML:
    <script type="text/javascript">
         $.ajax({
             type: 'GET',
             url: '/things/show/4f1d77bb3a13870ff0783c25',
             dataType: 'xml',
             success : function(data) {
                alert(data);
             }
         });
    </script>
Produces:
    <com.place.model.Thing>
        <id>
            <__time>1327331259</__time>
            <__machine>974358287</__machine>
            <__inc>-260555739</__inc>
            <__new>false</__new>
        </id>
        <name>Stack Overflow</name>
    </com.place.model.Thing>

我必须让getId()方法返回一个字符串。这是让Jackson停止序列化ObjectId的唯一方法

public String getId() {
    if (id != null) {
        return id.toString();
    } else {
        return null;
    }
}

public void setId(ObjectId id) {
    this.id = id;
}

setId()仍然必须是ObjectId,以便Mongo(及其驱动程序)可以正确设置ID

前面的答案确实奏效了,但它很难看,也没有经过深思熟虑——这是一个明确的解决问题的方法

真正的问题是反序列化为其组件
MappingJacksonJsonView
查看对象是什么,然后开始处理它。JSON中看到的反序列化字段是组成JSON的字段。要停止此类对象的序列化/反序列化,必须配置扩展的
CustomObjectMapper

以下是
自定义对象映射器

public class CustomObjectMapper extends ObjectMapper {

    public CustomObjectMapper() {
        CustomSerializerFactory sf = new CustomSerializerFactory();
        sf.addSpecificMapping(ObjectId.class, new ObjectIdSerializer());
        this.setSerializerFactory(sf);
    }
}
以下是
CustomObjectMapper
使用的
ObjectsSerializer

public class ObjectIdSerializer extends SerializerBase<ObjectId> {

    protected ObjectIdSerializer(Class<ObjectId> t) {
        super(t);
    }

    public ObjectIdSerializer() {
        this(ObjectId.class);
    }

    @Override
    public void serialize(ObjectId value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException {
        jgen.writeString(value.toString());
    }
}

您基本上是在告诉Jackson如何序列化/反序列化这个特定对象。工作起来很有魅力。

默认情况下,Jackson提供所接收对象的序列化。ObjectId返回对象,在转换为JSON后其属性可见。您需要指定所需的序列化类型,在本例中为stringThing用于创建ThingRepository的实体类将如下所示:

public class Thing {
    @Id
    @JsonSerialize(using= ToStringSerializer.class)
    ObjectId id;

    String name;
}

这里请注意添加的anotation@JsonSerialize(使用=ToStringSerializer.class),它指示将ObjectID序列化为字符串。

不需要自定义序列化程序。可以使用简单的串化器。
public class ObjectIdSerializer extends SerializerBase<ObjectId> {

    protected ObjectIdSerializer(Class<ObjectId> t) {
        super(t);
    }

    public ObjectIdSerializer() {
        this(ObjectId.class);
    }

    @Override
    public void serialize(ObjectId value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException {
        jgen.writeString(value.toString());
    }
}
@Bean(name = "jsonView")
public MappingJacksonJsonView jsonView() {
    final MappingJacksonJsonView mappingJacksonJsonView = new MappingJacksonJsonView();
    mappingJacksonJsonView.setContentType("application/json");
    mappingJacksonJsonView.setObjectMapper(new CustomObjectMapper());
    return mappingJacksonJsonView;
}
public class Thing {
    @Id
    @JsonSerialize(using= ToStringSerializer.class)
    ObjectId id;

    String name;
}