2012-01-30 7 views
4

내 SpringMVC 응용 프로그램에서 MappingJacksonJsonView를 사용하여 내 컨트롤러에서 JSON을 렌더링하고 있습니다. 내 객체의 ObjectId를 .toString으로 렌더링하고 싶지만 대신 ObjectId를 해당 부분으로 직렬화합니다. 그것은 내 속도/JSP 페이지에서 잘 작동합니다 : 얻기에서 MappingJacksonJsonView를 막을 방법은java spring MappingJacksonJsonView toString to mongodb 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> 

이 있음을 ObjectId가 밖으로 많은 정보? 모든 정보가 아니라 .toString() 메소드가 필요합니다.

감사합니다.

스프링 설정을 추가 :

@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이 구성 요소 부분으로 역 직렬화됩니다. MappingJacksonJsonView은 무엇인지, 객체인지를보고 ObjectId을보고 작업을 시작합니다. JSON에서 비 직렬화 된 필드는 ObjectId을 구성하는 필드입니다. 이러한 객체의 직렬화/직렬화를 중지하려면 을 확장하는 CustomObjectMapper을 구성해야합니다. 여기

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

기본적으로 이 특정 객체를 직렬화/비 직렬화하는 방법을 Jackson에게 알려줍니다. 매력처럼 작동합니다.

1

난 그냥 getId() 메소드는 문자열을 반환했습니다. Jackson이 ObjectId의 직렬화를 중지하게하는 유일한 방법이었습니다.

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

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

setId()는 여전히 Mongo (및 해당 드라이버)가 ID를 올바르게 설정할 수 있도록 ObjectId 여야합니다.