Nối tiếp với Jackson (JSON) - nhận được Không có serializer nào được tìm thấy?


262

Tôi có một ngoại lệ khi cố gắng tuần tự hóa một đối tượng rất đơn giản bằng cách sử dụng Jackson. Lỗi:

org.codehaus.jackson.map.JsonMappingException: Không tìm thấy trình tuần tự hóa nào cho lớp MyPackage.TestA và không có thuộc tính nào được phát hiện để tạo BeanSerializer (để tránh ngoại lệ, vô hiệu hóa serializationConfig.Feature.FAIL_ON_EMPTY_BEANS))

Dưới đây là lớp đơn giản và mã để tuần tự hóa.

Bất cứ ai có thể cho tôi biết lý do tại sao tôi nhận được lỗi này?

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

Tôi đã viết một bài về Cách viết một Trình tuần tự tùy chỉnh với Jackson có thể hữu ích với một số người.
Sam Berry

Câu trả lời:


329

Như đã mô tả, cấu hình mặc định của một ObjectMapperthể hiện là chỉ truy cập các thuộc tính là các trường công khai hoặc có getters / setters công khai. Một cách khác để thay đổi định nghĩa lớp để làm cho trường công khai hoặc để cung cấp một getter / setter công khai là chỉ định (cho bên dưới VisibilityChecker) một quy tắc hiển thị thuộc tính khác. Jackson 1.9 cung cấp ObjectMapper.setVisibility()phương pháp thuận tiện để làm như vậy. Đối với ví dụ trong câu hỏi ban đầu, tôi có thể định cấu hình câu này là

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

Đối với Jackson> 2.0:

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

Để biết thêm thông tin và chi tiết về các tùy chọn cấu hình liên quan, tôi khuyên bạn nên xem lại JavaDocsObjectMapper.setVisibility() .


59
Điều này làm việc cho tôi. Kể từ Jackson 2.0, ObjectMapper # setVisibility lấy PropertyAccessor làm đối số đầu tiên. Oneliner tương đương là myObjectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
Dan Robinson

@DanRobinson Mình dùng tương tự. Nhưng thực sự tôi đang tạo tập tin yaml. vì vậy đối với JSONString là: {"term":{"call_failed":"true"}}nó đang tạo cấu trúc yaml như: filter: map: term: map: call_failed: "true"Tại sao nó lại tạo maptừ khóa? Làm thế nào tôi có thể loại bỏ nó?
Manish Kumar

7
Có lẽ tôi đã dành 8 giờ với lỗi này, không nhận ra rằng phương thức getter của tôi không có "công khai" trên đó..thật ngu ngốc
Mike Kellogg

1
Tôi gặp lỗi này khi chuyển đổi ClientResponse thành chuỗi bằng trình
ánh xạ

1
Bạn cũng có thể thêm chú thích @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)phía trên lớp của mình
veben

74

Để Jackson tuần tự hóa lớp đó, SomeStringtrường cần phải public(ngay bây giờ là cách ly mức gói) hoặc bạn cần xác định phương thức getter và setter cho nó.


5
Xin lưu ý câu trả lời này không chính xác - trường không cần phải công khai hoặc có getter và setter. Trong một câu trả lời khác cho câu hỏi này, tôi đã cung cấp một cấu hình thay thế không yêu cầu thay đổi cấu trúc dữ liệu gốc để được tuần tự hóa.
Lập trình viên Bruce

9
Câu trả lời là hữu ích, ngay cả khi không chính xác 100%. Tôi đã quên đặt 'công khai' trên các lọ của mình, và điều này đã chỉ ra điều đó. Cảm ơn!
ChrisPhoenix

54

Tôi có cùng một vấn đề trong mã nguồn của tôi. Tôi vừa thêm

người đi

setter

Vấn đề đã được giải quyết.


1
Đã thử nhiều thứ khác nhau, và giải pháp đơn giản như thế này .... và nó nói khá rõ: "không có thuộc tính nào được phát hiện để tạo".
aks

2
@PhilipRego Ông có nghĩa là ông đã thêm một getter và setter cho trường.
Paul

Tôi sử dụng thư viện lombok, vì vậy tôi chỉ cần thêm anot Getter và Setter. Và mọi thứ đều ổn. Cảm ơn.
Rahmat Hidayat

yeah, getters và setters được sử dụng cho Jackson serialization./deserialization
Ikhiloya Imokhai

25

Vấn đề trong trường hợp của tôi là Jackson đã cố gắng tuần tự hóa một đối tượng trống rỗng không có thuộc tính cũng như phương thức.

Như được đề xuất trong ngoại lệ, tôi đã thêm dòng sau để tránh thất bại đối với đậu rỗng:

Dành cho Jackson 1.9

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

Dành cho Jackson 2.X

myObjectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);

Bạn có thể tìm thấy một ví dụ đơn giản về jackson vô hiệu hóa fail_on_empty_beans


9

Tôi gặp vấn đề tương tự đối với một lớp con nơi tôi có quyền điều khiển, trình ánh xạ đối tượng nằm trong một mô-đun chung và không thể truy cập được. Tôi đã giải quyết nó bằng cách thêm chú thích này cho lớp con tôi có đối tượng sẽ được nối tiếp.

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)

7

Nếu bạn có thể chỉnh sửa lớp chứa đối tượng đó, tôi thường chỉ cần thêm chú thích

import com.fasterxml.jackson.annotation.JsonIgnore;

@JsonIgnore 
NonSerializeableClass obj;

2
Lỗi này cũng xảy ra khi lớp của bạn có một phương thức có tên bắt đầu bằng get ... Ví dụ NonSerializableClass getMyNonSerializableObject (). Jackson cố gắng nối tiếp nó và thất bại. Để giải quyết vấn đề này, chỉ cần thêm @JsonIgnore hoặc đổi tên phương thức.
Alexey Podlasov

1
Đã sử dụng phiên bản cũ hơn:org.codehaus.jackson.annotate.JsonIgnore
AlikElzin-kilaka

6

Lỗi này cũng được đưa ra nếu bạn quên thêm phương thức .build () vào trạng thái trả về của bạn.

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

Tôi đã gặp lỗi sau khi không có phương thức build ():

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

4

SpringBoot2.0 Tôi giải quyết nó bằng mã theo:

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

1
bạn nên giữ cho mô hình của bạn có các phương thức getter và setter.
Janus

1
Chào mừng đến với SO! Cảm ơn đã đóng góp. Vui lòng thêm một lời giải thích cho câu trả lời của bạn, để nó rõ ràng mã đó làm gì, tại sao nó hoạt động và cách nó trả lời câu hỏi OP.
Max Vollmer

Điều này đã giúp tôi! Nhưng theo tôi, bạn nên tiêm ObjectMapper của bối cảnh và cấu hình nó sau đó thay vì tạo một cái mới.
RoBeaToZ

3

Đối với các ứng dụng Java của Oracle, hãy thêm phần này sau khi ObjectMapperkhởi tạo:

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

2

Tôi gặp vấn đề tương tự với việc lười tải thông qua đối tượng proxy ngủ đông. Có xung quanh nó bằng cách chú thích lớp có các thuộc tính riêng tư được tải lười biếng với:

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

Điều này đã giải quyết vấn đề của tôi. Bạn có thể cho tôi biết chính xác những gì nó làm?
Scarface

2

Vấn đề có thể là do bạn đã khai báo biến là private. Nếu bạn thay đổi nó public, nó hoạt động.

Tùy chọn tốt hơn là sử dụng các phương thức getter và setter cho nó.

Điều này sẽ giải quyết vấn đề!


2

Tôi tìm thấy ít nhất ba cách để làm điều này:

  1. Thêm vào public getters vào thực thể của bạn mà bạn cố gắng tuần tự hóa;
  2. Thêm một chú thích ở đầu thực thể, nếu bạn không muốn public getters. Điều này sẽ thay đổi mặc định cho Jackson từ Visbility=DEFAULTsang@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) nơi bất kỳ bổ truy cập được chấp nhận;
  3. Thay đổi ObjectMappertoàn cầu của bạn bằng cách thiết lập objectMapperInstance.setVisibility(JsonMethod.FIELD, Visibility.ANY);. Điều này nên tránh nếu bạn không cần chức năng này trên toàn cầu.

Chọn dựa trên nhu cầu của bạn.


2

Dưới đây là ba tùy chọn:

  1. Dữ liệu / lớp được truy cập cần phải được public
  2. Nếu không public, thêm getters & setters
  3. Hoặc thêm @JsonIgnore("context")

1

Vui lòng sử dụng điều này ở cấp lớp cho đậu:

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

1

thêm setter và getter cũng sẽ giải quyết vấn đề khi nó được sửa cho tôi. Ví dụ:

public class TestA {
    String SomeString = "asd";

    public String getSomeString () {        return SomeString ;     }

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

1

Tôi chỉ có getters, sau khi thêm setters quá, vấn đề được giải quyết.


0

Mặc dù tôi đã thêm getters và setters tôi đã nhận được cùng một lỗi. Sau đó tôi đã tìm thấy một lỗi, đó là theo lời khuyên của Sonar, tôi đã đưa ra các getters và setters như được bảo vệ gây ra vấn đề. Khi tôi đã sửa nó hoạt động như exppected.


0

trong khởi động mùa xuân 2.2.5

sau khi thêm getter và setter

tôi đã thêm @JsonIgnore trên đầu trang.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.