스프링 및 JsonTypeInfo 주석을 사용하여 JSON을 다형 객체모델로 시리얼 해제
Spring MVC(v3.2.0)에는 다음과 같은 오브젝트 모델이 있습니다.릴리즈) 웹 어플리케이션:
public class Order {
private Payment payment;
}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = As.WRAPPER_OBJECT)
@JsonSubTypes.Type(name = "creditCardPayment", value = CreditCardPayment.class)
public interface Payment {}
@JsonTypeName("creditCardPayment")
public class CreditCardPayment implements Payment {}
Order 클래스를 JSON으로 시리얼화하면 다음과 같은 결과가 나타납니다(원하는 대로).
{
"payment" : {
"creditCardPayment": {
...
}
}
유감스럽게도 위의 JSON을 사용하여 오브젝트모델로 역직렬화하려고 하면 다음과 같은 예외가 발생합니다.
JSON을 읽을 수 없음: 유형 ID 'creditCardPayment'를 [Source: org.apache.catalina.connector]에서 [simple type, class Payment]의 하위 유형으로 확인할 수 없습니다.Coyote Input Stream @19629355; 회선: 1, 열: 58] (참조 체인 경유:Order [ " payment " ] ;네스트된 예외는 com.fasterxml.jackson.databind 입니다.Json Mapping Exception:유형 ID 'creditCardPayment'를 [Source: org.apache.catalina.connector]에서 [simple type, class Payment]의 하위 유형으로 확인할 수 없습니다.Coyote Input Stream @19629355; 회선: 1, 열: 58] (참조 체인 경유:주문["지불"])
응용 프로그램은 다음과 같이 Spring JavaConf를 통해 설정됩니다.
@Configuration
@EnableWebMvc
public class AppWebConf extends WebMvcConfigurerAdapter {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(Include.NON_NULL);
objectMapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, false);
return objectMapper;
}
@Bean
public MappingJackson2HttpMessageConverter mappingJacksonMessageConverter() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(objectMapper());
return converter;
}
@Bean
public Jaxb2RootElementHttpMessageConverter jaxbMessageConverter() {
return new Jaxb2RootElementHttpMessageConverter();
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(jaxbMessageConverter());
converters.add(mappingJacksonMessageConverter());
}
}
테스트용으로 2가지 방법을 가진 컨트롤러가 있습니다.하나는 HTTP GET 요구를 위한 Order를 반환하고(이것은 동작), 다른 하나는 HTTP POST를 통한 Order를 접수합니다(이것은 실패).
@Controller
public class TestController {
@ResponseBody
@RequestMapping(value = "/test", method = RequestMethod.GET)
public Order getTest() {}
@RequestMapping(value = "/test", method = RequestMethod.POST)
public void postTest(@RequestBody order) {}
}
SO에 대한 다양한 논의에서 모든 제안을 시도해봤지만, 지금까지 아무런 성과가 없었습니다.내가 뭘 잘못하고 있는지 알아낼 수 있는 사람?
다음을 사용하여 하위 유형 등록 시도ObjectMapper.registerSubtypes주석을 사용하는 대신
방법registerSubtypes()동작합니다!
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="type")
public interface Geometry {
//...
}
public class Point implements Geometry{
//...
}
public class Polygon implements Geometry{
//...
}
public class LineString implements Geometry{
//...
}
GeoJson geojson= null;
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES);
mapper.registerSubtypes(Polygon.class,LineString.class,Point.class);
try {
geojson=mapper.readValue(source, GeoJson.class);
} catch (IOException e) {
e.printStackTrace();
}
주의 1: 인터페이스와 구현 클래스를 사용합니다.구현 클래스에 따라 잭슨이 클래스의 시리얼화를 해제하려면 Object Mapper의 "register Subtypes" 메서드를 사용하여 모든 클래스를 등록해야 합니다.
주 2: 또한 @JsonTypeInfo(use=JsonTypeInfo)를 사용합니다.ID.NAME, include=JsonTypeInfo.As.PROPERTY, property="type"을 인터페이스 주석으로 지정합니다.
매퍼가 POJO 값을 json으로 쓸 때 속성 순서를 정의할 수도 있습니다.
이 작업은 아래 주석을 사용하여 수행할 수 있습니다.
@JsonPropertyOrder({"type","crs","version","features"})
public class GeoJson {
private String type="FeatureCollection";
private List<Feature> features;
private String version="1.0.0";
private CRS crs = new CRS();
........
}
이게 도움이 됐으면 좋겠네요!
Drop Wizard 기반 서비스 작업 중 비슷한 문제가 발생했습니다.드롭 위저드 코드와 같은 방법으로 동작하지 않는 이유를 충분히 이해할 수 없지만, 원래의 투고에 있는 코드가 동작하지 않는 이유는 알 수 있습니다. @JsonSubTypes에서는 단일 값이 아닌 하위 유형의 배열을 필요로 합니다.★★★★★★★★★★★★★★...
@JsonSubTypes.Type(name = "creditCardPayment", value = CreditCardPayment.class)
...와 함께
@JsonSubTypes({ @JsonSubTypes.Type(name = "creditCardPayment", value = CreditCardPayment.class) })
당신의 코드가 작동하리라 믿습니다.
같은 에러 메세지가 표시되는 경우는, 검출되고 있는 서브 타입에 문제가 있는 경우가 있습니다.하거나, 하다를 .@JsonTypeName그를붙붙 붙붙붙다다
효과가 있었고, 는 다른 .com.fasterxml.jackson.databind.JsonMappingException: Could not resolve type id into a subtype of Blah하지 registerSubtypes. 부모 클래스에 다음 주석을 추가할 수 있습니다.
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "type")
, 이 는 '다르다'라는 점에 주의하세요.JsonTypeInfo.Id.CLASSJsonTypeInfo.Id.NAME단점은 생성된 JSON에 완전한 네임스페이스를 포함한 전체 클래스 이름이 포함된다는 것입니다.장점은 서브타입 등록에 대해 걱정할 필요가 없다는 것입니다.
에는 내, 음, 음, 음, 음, 음, 음, 음, 음, in, in, in, in, in, in, in, in, in,defaultImpl = SomeClass.class하려고 했습니다.
한 것을 하였습니다(JSON ).CreditCardPaymentname)을deserializer class my class name ) 。
{
"type": "CreditCardPayment",
...
}
언급URL : https://stackoverflow.com/questions/19239413/de-serializing-json-to-polymorphic-object-model-using-spring-and-jsontypeinfo-an
'programing' 카테고리의 다른 글
| 리액트 라우터 2.0.0-rc5에서 현재 루트를 얻는 방법 (0) | 2023.02.22 |
|---|---|
| SQL에서 GROUP BY/집약 기능의 혼란 (0) | 2023.02.22 |
| restsharp를 사용하여 json 문자열 직렬화 해제 (0) | 2023.02.22 |
| 루트 파라미터 변경 또는 쿼리 변경 시 React가 컴포넌트 데이터를 새로고침하지 않음 (0) | 2023.02.22 |
| woocommerce get_woocommerce_displays() (0) | 2023.02.22 |