2012-01-30 37 views
4

我在我的SpringMVC应用程序中使用MappingJacksonJsonView从我的控制器呈现JSON。我想从我的对象的ObjectId呈现为.toString,而是它将ObjectId序列化到它的部分。它工作得很好,在我的速度/ JSP页面:java spring MappingJacksonJsonView没有对mongodb做toString ObjectId

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()方法,而不是所有的细节。

谢谢。

添加Spring配置:

@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"; 
    } 
} 

回答

1

以前的答案有窍门,但它很丑陋,没有经过深思熟虑 - 一个明确的解决方法来解决问题。

真正的问题是,ObjectId反序列化成其组成部分。​​看到ObjectId它是什么,一个对象,并去工作。在JSON中看到的反序列化字段是组成ObjectId的字段。要停止这样的对象的序列化/反序列化,您必须配置延伸ObjectMapperCustomObjectMapper

这里是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 -annotated类改变:

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

你基本上告诉杰克逊如何序列化/反序列化这个特定对象。奇迹般有效。

1

我只是让getId()方法返回一个字符串。这是让杰克逊停止序列化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。