java Spring MappingJacksonJsonView在mongodb ObjectId上不执行toString [英] java spring MappingJacksonJsonView not doing toString on mongodb ObjectId

查看:66
本文介绍了java Spring MappingJacksonJsonView在mongodb ObjectId上不执行toString的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在SpringMVC应用程序中使用MappingJacksonJsonView从控制器渲染JSON.我希望对象中的ObjectId呈现为.toString,但相反它将ObjectId序列化为其部分.在我的Velocity/JSP页面中它可以正常工作:

I am using the MappingJacksonJsonView in my SpringMVC application to render JSON from my controllers. I want the ObjectId from my object to render as .toString but instead it serializes the ObjectId into its parts. It works just fine in my Velocity/JSP pages:

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>

是否有一种方法可以阻止MappingJacksonJsonView从ObjectId中获取大量信息?我只需要.toString()方法,而不是所有详细信息.

Is there a way to stop MappingJacksonJsonView from getting that much information out of the ObjectId? I just want the .toString() method, not all the details.

谢谢.

添加Spring配置:

Adding the Spring config:

@Configuration
@EnableWebMvc
public class MyConfiguration {

    @Bean(name = "viewResolver")
    public ContentNegotiatingViewResolver viewResolver() {
        ContentNegotiatingViewResolver contentNegotiatingViewResolver = new ContentNegotiatingViewResolver();
        contentNegotiatingViewResolver.setOrder(1);
        contentNegotiatingViewResolver.setFavorPathExtension(true);
        contentNegotiatingViewResolver.setFavorParameter(true);
        contentNegotiatingViewResolver.setIgnoreAcceptHeader(false);
        Map<String, String> mediaTypes = new HashMap<String, String>();
        mediaTypes.put("json", "application/x-json");
        mediaTypes.put("json", "text/json");
        mediaTypes.put("json", "text/x-json");
        mediaTypes.put("json", "application/json");
        mediaTypes.put("xml", "text/xml");
        mediaTypes.put("xml", "application/xml");
        contentNegotiatingViewResolver.setMediaTypes(mediaTypes);
        List<View> defaultViews = new ArrayList<View>();
        defaultViews.add(xmlView());
        defaultViews.add(jsonView());
        contentNegotiatingViewResolver.setDefaultViews(defaultViews);
        return contentNegotiatingViewResolver;
    }

    @Bean(name = "xStreamMarshaller")
    public XStreamMarshaller xStreamMarshaller() {
        return new XStreamMarshaller();
    }

    @Bean(name = "xmlView")
    public MarshallingView xmlView() {
        MarshallingView marshallingView = new MarshallingView(xStreamMarshaller());
        marshallingView.setContentType("application/xml");
        return marshallingView;
    }

    @Bean(name = "jsonView")
    public MappingJacksonJsonView jsonView() {
        MappingJacksonJsonView mappingJacksonJsonView = new MappingJacksonJsonView();
        mappingJacksonJsonView.setContentType("application/json");
        return mappingJacksonJsonView;
    }
}

还有我的控制器:

@Controller
@RequestMapping(value = { "/things" })
public class ThingController {

    @Autowired
    private ThingRepository thingRepository;

    @RequestMapping(value = { "/show/{thingId}" }, method = RequestMethod.GET)
    public String show(@PathVariable ObjectId thingId, Model model) {
        model.addAttribute("thing", thingRepository.findOne(thingId));
        return "things/show";
    }
}

推荐答案

以前的答案可以解决问题,但这很丑陋,没有经过深思熟虑-一种解决问题的清晰方法.

Previous answer did the trick, but it was ugly and not well thought out - a clear workaround to actually fixing the problem.

真正的问题是 ObjectId 反序列化为其组成部分. MappingJacksonJsonView看到 ObjectId ,一个对象,然后对其进行处理.在JSON中看到的反序列化字段是构成的字段ObjectId .要停止此类对象的序列化/反序列化,您必须配置扩展

The real issue is that ObjectId deserializes into its component parts. MappingJacksonJsonView sees ObjectId for what it is, an object, and goes to work on it. The deserialized fields being seen in the JSON are the fields that make up an ObjectId. To stop the serialization/deserialization of such an object, you have to configure a CustomObjectMapper that extends ObjectMapper.

这是CustomeObjectMapper:

public class CustomObjectMapper extends ObjectMapper {

    public CustomObjectMapper() {
        CustomSerializerFactory sf = new CustomSerializerFactory();
        sf.addSpecificMapping(ObjectId.class, new ObjectIdSerializer());
        this.setSerializerFactory(sf);
    }
}

这是CustomObjectMapper使用的ObjectIdSerializer:

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());
    }
}

这是在@Configuration注释的类中需要更改的内容:

And here is what needs to change in your @Configuration-annotated class:

@Bean(name = "jsonView")
public MappingJacksonJsonView jsonView() {
    final MappingJacksonJsonView mappingJacksonJsonView = new MappingJacksonJsonView();
    mappingJacksonJsonView.setContentType("application/json");
    mappingJacksonJsonView.setObjectMapper(new CustomObjectMapper());
    return mappingJacksonJsonView;
}

您基本上是在告诉Jackson如何序列化/反序列化此特定对象.就像魅力一样.

You are basically telling Jackson how to serialize/deserialize this particular object. Works like a charm.

这篇关于java Spring MappingJacksonJsonView在mongodb ObjectId上不执行toString的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆