Jackson으로 직렬화 (JSON)- "직렬화기를 찾을 수 없습니다"?


262

Jackson을 사용하여 매우 간단한 객체를 직렬화하려고 할 때 예외가 발생합니다. 오류:

org.codehaus.jackson.map.JsonMappingException : MyPackage.TestA 클래스에 대한 시리얼 라이저가없고 BeanSerializer를 작성하는 특성이 발견되지 않았습니다 (예외를 피하기 위해 SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS 비활성화)

아래는 직렬화 할 간단한 클래스와 코드입니다.

아무도 내가이 오류가 발생하는 이유를 말할 수 있습니까?

public class TestA {
    String SomeString = "asd";
}

TestA testA = new TestA();
ObjectMapper om = new ObjectMapper();
try {
    String testAString = om.writeValueAsString(testA); // error here!

    TestA newTestA = om.readValue(testAString, TestA.class);
} catch (JsonGenerationException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (JsonMappingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

답변:


329

이미 설명한 바와 같이 ObjectMapper인스턴스 의 기본 구성 은 공용 필드이거나 공용 게터 / 세터가있는 속성에만 액세스하는 것입니다. 필드를 공용으로 만들거나 공용 게터 / 세터를 제공하기 위해 클래스 정의를 변경하는 대안 VisibilityChecker은 다른 속성 표시 규칙을 지정하는 것입니다. Jackson 1.9는이를위한 ObjectMapper.setVisibility()편리한 방법을 제공합니다 . 원래 질문의 예에서는 다음과 같이 구성했을 것입니다.

myObjectMapper.setVisibility(JsonMethod.FIELD, Visibility.ANY);

Jackson> 2.0의 경우 :

myObjectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);

관련 구성 옵션에 대한 자세한 정보 및 세부 사항 은 JavaDocs on을ObjectMapper.setVisibility() 검토 하는 것이 좋습니다 .


59
이것은 나를 위해 일했습니다. Jackson 2.0부터 ObjectMapper # setVisibility는 PropertyAccessor를 첫 번째 인수로 사용합니다. 동등한 oneliner는 myObjectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
Dan Robinson

@ DanRobinson 나는 똑같이 사용했다. 그러나 실제로 yaml 파일을 생성 중입니다. JSONString의 경우 : {"term":{"call_failed":"true"}}yaml 구조를 다음과 같이 생성합니다. filter: map: term: map: call_failed: "true"map키워드를 생성 합니까? 어떻게 제거 할 수 있습니까?
Manish Kumar

7
아마 내 게터 방법은 it..so에 바보 "공개"하지 않았다 실현하지,이 오류와 함께 8 시간 동안
마이크 켈로그

1
객체 매퍼를 사용하여 ClientResponse를 문자열로 변환하는 동안이 오류가 발생합니다
VdeX

1
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)클래스 위에 주석을 추가 할 수도 있습니다
veben

74

Jackson이 해당 클래스를 직렬화하려면 SomeString필드가 public(지금은 패키지 레벨 분리 임) 또는 getter 및 setter 메소드를 정의해야합니다.


5
이 답변은 잘못되었습니다. 필드는 공개적이거나 게터와 세터가 필요 하지 않습니다 . 이 질문에 대한 또 다른 대답으로, 원래 데이터 구조를 변경하지 않고도 직렬화를 해제 할 수있는 대체 구성을 제공했습니다.
프로그래머 브루스

9
정답은 100 % 정확하지 않더라도 유용합니다. 나는 내 vars에 '공개'를 놓는 것을 잊었고, 이것은 그것을 지적했다. 감사!
ChrisPhoenix

53

내 소스 코드에서 동일한 문제가 있습니다. 방금 추가했습니다

얻는 사람

세터

문제가 해결되었습니다.


1
많은 다른 것들을 시험해 보았고, 해결책은 이것처럼 간단합니다. ... 그리고 "생성 할 속성이 발견되지 않았습니다"라고 아주 명확하게 말합니다.
aks

2
@PhilipRego 그는 필드에 게터와 세터를 추가했음을 의미합니다.
Paul

나는 롬복 라이브러리를 사용하므로 Getter와 Setter 주석을 추가합니다. 그리고 모든 것이 잘되었습니다. 감사.
Rahmat Hidayat

그래, getter 및 setter는 잭슨 serialization./deserialization에 사용되는
Ikhiloya Imokhai에게

25

필자의 경우 문제는 Jackson이 속성이나 메소드없이 빈 객체를 직렬화하려고 시도했다는 것입니다.

예외에서 제안한 것처럼 빈 빈에서 실패를 피하기 위해 다음 줄을 추가했습니다.

잭슨 1.9

myObjectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);

잭슨 2.X

myObjectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);

jackson disable fail_on_empty_beans 에서 간단한 예를 찾을 수 있습니다.


9

나는 컨트롤을 가진 자식 클래스에 대해 같은 문제가 있었고, 객체 매퍼는 공통 모듈에 있었고 액세스 할 수 없었습니다. 객체를 직렬화 할 자식 클래스 에이 주석을 추가하여 문제를 해결했습니다.

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)

7

해당 객체가 포함 된 클래스를 편집 할 수 있다면 일반적으로 주석을 추가합니다.

import com.fasterxml.jackson.annotation.JsonIgnore;

@JsonIgnore 
NonSerializeableClass obj;

2
이 오류는 클래스에 get ...으로 시작하는 이름을 가진 메소드가있는 경우에도 발생합니다. 예를 들어 NonSerializableClass getMyNonSerializableObject (). Jackson은 직렬화하려고 시도했지만 실패합니다. 이 문제를 해결하려면 @JsonIgnore를 추가하거나 메소드 이름을 바꾸십시오.
Alexey Podlasov

1
이전 버전을 사용했습니다 :org.codehaus.jackson.annotate.JsonIgnore
AlikElzin-kilaka

6

이 오류는 반환 상태에 .build () 메서드를 추가하지 않은 경우에도 발생합니다.

return Response.status(Status.OK);         // fails
return Response.status(Status.OK).build(); // works

build () 메소드없이 다음 오류가 발생했습니다.

org.codehaus.jackson.map.JsonMappingException: No serializer found for class com.sun.jersey.core.spi.factory.ResponseBuilderImpl

4

SpringBoot2.0 , 다음 코드로 해결합니다 :

@Bean public ObjectMapper objectMapper() {
 return new ObjectMapper().disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);}

1
모델에 getter 및 setter 메소드가 있어야합니다.
야누스

1
SO에 오신 것을 환영합니다! 기여해 주셔서 감사합니다. 답변에 설명을 추가하여 코드의 기능, 작동 이유 및 OP 질문에 어떻게 대답하는지 명확하게하십시오.
Max Vollmer

이것은 나를 도왔다! 그러나 내 의견으로는, 당신은 컨텍스트의 ObjectMapper를 주입하고 새로운 컨텍스트를 생성하기보다는 나중에 구성해야합니다.
RoBeaToZ

3

Oracle Java 애플리케이션의 경우 ObjectMapper인스턴스화 후이를 추가하십시오 .

mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);

2

최대 절전 모드 프록시 객체를 통한 지연로드와 비슷한 문제가있었습니다. 게으른로드 된 개인 속성이있는 클래스에 다음과 같이 주석을 달아주었습니다.

@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})

이것은 내 문제를 해결했다. 이것이 정확히 무엇인지 말해 줄 수 있습니까?
scarface

2

변수를로 선언했기 때문에 문제가있을 수 있습니다 private. 로 변경 public하면 작동합니다.

더 나은 옵션은 getter 및 setter 메소드를 사용하는 것입니다.

문제가 해결됩니다!


2

나는 이것을하는 적어도 세 가지 방법을 발견했다.

  1. public getters직렬화하려는 엔티티를 추가하십시오 .
  2. 원하지 않는 경우 엔터티 상단에 주석을 추가하십시오 public getters. 이것은에서 잭슨의 기본 변경됩니다 Visbility=DEFAULT에 대한 @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)모든 액세스 수정이 허용하는 경우;
  3. ObjectMapper을 설정 하여 전 세계를 변경하십시오 objectMapperInstance.setVisibility(JsonMethod.FIELD, Visibility.ANY);. 전 세계적으로이 기능이 필요하지 않은 경우이를 피해야합니다.

필요에 따라 선택하십시오.


2

세 가지 옵션은 다음과 같습니다.

  1. 액세스 된 데이터 / 클래스는 public
  2. 그렇지 않은 경우 게터 및 세터public 추가
  3. 또는 추가 @JsonIgnore("context")

1

Bean의 클래스 레벨에서 이것을 사용하십시오.

@JsonIgnoreProperties(value={"hibernateLazyInitializer","handler","fieldHandler"})

1

setter와 getter를 추가하면 문제가 해결되었습니다. 예를 들어 :

public class TestA {
    String SomeString = "asd";

    public String getSomeString () {        return SomeString ;     }

    public void setSomeString (String SS ) {        SomeString = SS ;   } 
}


0

게터와 세터를 추가했지만 같은 오류가 발생했습니다. 나중에 나는 버그를 발견했습니다. 즉, Sonar의 조언에 의해 게터와 세터가 보호 된 것으로 문제를 일으켰습니다. 일단 그것이 예상대로 작동한다고 고쳤습니다.


0

봄 부팅 2.2.5

게터와 세터를 추가 한 후

필드 위에 @JsonIgnore를 추가했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.