2012-01-30 50 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。

相關問題