2012-03-01 2 views
2

Spring MVC 및 JSON 지원과 관련하여 하나의 문제가 있습니다. 하나의 아약스 호출을 만들어 일부 데이터를 얻었고이 데이터를 루트 값을 포함하여 json 형식으로 가져 오려고합니다. 엔티티에서 에 사용되기 때문에 엔티티에서 JABX 주석을 사용하고 있습니다.스프링 MVC와 Jackson 매핑이 json에서 루트 요소를 반환하지 않습니다.

public class JaxbJacksonObjectMapper extends ObjectMapper { 

    public JaxbJacksonObjectMapper() { 
     final AnnotationIntrospector introspector = new JaxbAnnotationIntrospector(); 

     this.configure(org.codehaus.jackson.map.DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true); 
     super.getDeserializationConfig().withAnnotationIntrospector(introspector); 

     this.configure(org.codehaus.jackson.map.SerializationConfig.Feature.WRAP_ROOT_VALUE, true); 
     super.getSerializationConfig().withAnnotationIntrospector(introspector); 
    } 
} 
:
this.configure(org.codehaus.jackson.map.DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true); 

그래서 나는 codehaus 하나를 확장하고 다음과 같습니다 하나 objectMapper을 만들어 :

내가 Jackson에 포함 된 루트 값을 얻기 위해 그것을 읽고, 나는이 방법을 사용한다

스프링은이 매퍼를 사용하기 위해 다음과 같은 라인을 설정했다 :

<beans:bean id="customObjectMapper" class="com.test.package.config.JaxbJacksonObjectMapper" /> 

<beans:bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> 
    <beans:property name="objectMapper" ref="customObjectMapper" /> 
</beans:bean> 

<beans:bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> 
    <beans:property name="messageConverters"> 
     <beans:list> 
      <beans:ref bean="jsonMessageConverter"/> 
     </beans:list> 
    </beans:property> 
</beans:bean> 

그리고 내 실체는 다음과 같다 :

@XmlRootElement(name = "collection") 
public class Issuers { 
    private List<Issuer> issuers; 
} 

문제는 Spring 3.1가 브라우저에 발행을 JSON 객체를 반환 할 때이 collection 루트 요소를 포함하지 않습니다.

이 문제를 해결하는 방법에 대해 알고 싶습니다.

감사합니다.

+0

http://stackoverflow.com/q/2435527/923560는 경우 비슷한 문제 – Abdull

+0

에 대해 설명 이 문제를 해결할 수 있었는지 알려주세요. – Marco

답변

0

"발급자"를 일반적인 홀더 개체로 감싸십시오. 그게 잭슨과 스프링과 함께 할 때하는 일입니다.

class JSONResponse { 

    private Object collection; 

    public JSONResponse(Object collection) { 
     this.collection = collection; 
    } 
    public Object getCollection() { 
     return collection; 
    } 
} 

...

@RequestMappin(...) 
@ResponseBody 
public Object someHandler(...) { 
    ... 
    return new JSONResponse(issuers); 
} 
+0

그 한 가지 옵션, 감사 수 있습니다. 그러나 모든 단일 요청에서 변경하지 않아도되도록 더 깨끗한 솔루션을 얻고 싶습니다. 하지만 최악의 경우 ... –

+0

봄 구성이 옳지 않은 것 같습니다. 그것은 messageconverters를 무시하지 않았으므로, 내가 작성한 Mapper를 사용하지 않았습니다. 은을 대체하려면 오른쪽 스프링 설정은 다음과 같습니다 ' <주석 중심> <메시지 컨버터> <콩 : 콩 클래스 = "org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> <콩 :

+0

이제 루트 요소를 가져오고 있습니다. jabx 주석,하지만 클래스의 이름. 그 문제를 해결하는 방법에 대해 알고 싶습니다. 잭슨 매퍼 (Jackson mapper)에서 내가 만든 몇 가지 문제와 관련이있을거야. –

0

이 스프링 구성을 잘하지 않았다 것 같다. 그것은 messageconverters를 무시하지 않았으므로, 내가 작성한 Mapper를 사용하지 않았습니다.

은을 대체하려면 오른쪽 스프링 설정은 다음과 같습니다

<annotation-driven> 
    <message-converters> 
     <beans:bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> 
      <beans:property name="objectMapper" ref="customObjectMapper" /> 
     </beans:bean> 
    </message-converters> 
</annotation-driven> 

는 지금은 루트 요소를 얻고 있지만 jabx 주석에 주어진 이름,하지만 클래스의 이름을 가지고 있지 않습니다.

새로운 메소드 (withAnnotiationIntrospector)가 제대로 작동하지 않거나 뭔가 누락 된 것으로 보입니다. 그러나 사용되지 않는 것을 사용하면 JABX 레이블에 정의 된 적절한 루트 이름을 얻게됩니다.

public JaxbJacksonObjectMapper() { 
    final AnnotationIntrospector introspector = new JaxbAnnotationIntrospector(); 

    this.configure(org.codehaus.jackson.map.SerializationConfig.Feature.WRAP_ROOT_VALUE, true); 
    this.configure(org.codehaus.jackson.map.DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true); 

    // When using the non deprecated method (withAnnotationIntrospector), 
    // there are problems with JAXB/JSON parser so don't use right now 

    super.getDeserializationConfig().setAnnotationIntrospector(introspector); 
    super.getSerializationConfig().setAnnotationIntrospector(introspector); 
} 
3

이 방법 withAnnotiationIntrospectorAnnotiationIntrospector을 설정하지 않는 것 같다. 대신 new DeserializationConfig/SerializationConfig 개체를 반환합니다 (올바른 AnnotiationIntrospector).

그래서, JaxbJacksonObjectMapper의 나의 버전 :

public class JaxbJacksonObjectMapper extends ObjectMapper { 

    public JaxbJacksonObjectMapper() { 
     super(); 

     final AnnotationIntrospector introspector = new JaxbAnnotationIntrospector(); 

     this.configure(org.codehaus.jackson.map.DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true); 
     this.configure(org.codehaus.jackson.map.SerializationConfig.Feature.WRAP_ROOT_VALUE, true); 

     this.setDeserializationConfig(this.getDeserializationConfig().withAnnotationIntrospector(introspector)); 
     this.setSerializationConfig(this.getSerializationConfig().withAnnotationIntrospector(introspector)); 

    } 
} 

는 이제 @XmlRootElement, @XmlTransient 등을 지원합니다.하나 개의 문장 다음이 사용에

0

대안 :

setAnnotationIntrospector(introspector); 

대신 다음 두 명령문,

super.getDeserializationConfig().setAnnotationIntrospector(introspector); 
super.getSerializationConfig().setAnnotationIntrospector(introspector); 
관련 문제