Не найден сериализатор для класса в пользовательском приложении Java AWS - PullRequest
1 голос
/ 18 июня 2019

Я создаю приложение Spring, в котором он вызывает информацию из API-интерфейса AWS и преобразует ее в JSON, чтобы приложение внешнего интерфейса могло переваривать и отображать. В настоящее время я пытаюсь вернуть список всех текущих сегментов S3 для учетной записи, но столкнулся с проблемой, когда ответ JSON:

статус ": 500, «ошибка»: «Внутренняя ошибка сервера», «message»: «Ошибка определения типа: [простой тип, класс software.amazon.awssdk.services.s3.model.Bucket]; вложенное исключение - com.fasterxml.jackson.databind.exc.InvalidDefinitionException: не найден сериализатор для программного обеспечения класса .amazon.awssdk.services.s3.model.Bucket и не обнаружены свойства для создания BeanSerializer (во избежание исключения отключите SerializationFeature.FAIL_ON_EMPTY_BEANS) (через цепочку ссылок: com.landsend.clouddashboard.data.Class.S3 [\ "bucketList \ "] -java.util.Collections $ UnmodifiableRandomAccessList [0])", "путь": "/ api / s3 / buckets"

Я создал класс с именем S3, который имеет частные переменные. Одним из них является тип List с именем bucketList. Этот класс имеет типичные методы получения и установки, связанные с этими переменными.

Я также попытался добавить это в файл application.properties:

spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false

Это привело к исчезновению ошибки, но я получил пустой файл JSON.

Класс контроллера

@RestController
@RequestMapping(value="/api")
public class S3Controller {

    @Autowired
    private S3Service s3Service;

    @RequestMapping(method= RequestMethod.GET, value="/s3/buckets")
    public S3 ListBuckets(){
        return s3Service.listBucket();
    }
}

Класс обслуживания

@Service
public class S3Service {

    private S3Access s3Access;

    @Autowired
    public S3Service(S3Access s3Access){
        this.s3Access = s3Access;
    }
    public S3 listBucket(){
        //Any Additional business logic would go here
        return s3Access.listBucket();
    }
}

Класс доступа

@Repository
public class S3Access implements S3Repository {

    @Autowired
    private S3 s3Instance;

    private Region region = Region.US_EAST_1;
    private S3Client s3Client = 
                     S3Client.builder().region(region).build();

    @Override
    public S3 listBucket() {
        ListBucketsRequest listBucketsRequest = ListBucketsRequest.builder().build();
        ListBucketsResponse listBucketsResponse = s3Client.listBuckets(listBucketsRequest);
        s3Instance.setBucketList(listBucketsResponse.buckets());
        return s3Instance;
    }
}

Класс конструктора S3

@Component
public class S3 {
    private String fileName;
    private String bucketName;
    private int bucketSize;
    private List<Bucket> bucketList;

    public List<Bucket> getBucketList() {
        return bucketList;
    }

    public void setBucketList(List<Bucket> bucketList) {
        this.bucketList = bucketList;
    }
}

Любые мысли о том, почему это не работает, приветствуются.

Ответы [ 2 ]

1 голос
/ 18 июня 2019

Проблема с классом Bucket . Jackson по умолчанию обрабатывает все предоставленные объекты как POJO -s. Каждый POJO должен иметь список getters / setters. В случае, если класс не имеет их, объект считается пустым. Если вы хотите сериализовать такие классы, вы можете:

  1. Создайте дополнительный POJO класс с getters и сопоставьте его с необработанным AWS класс к этому POJO.
  2. Реализовать и зарегистрировать сериализатор для этого класса.
  3. Преобразование модели AWS в Map -s и List -s вручную и их сериализацию.

Смотри также:

0 голосов
/ 18 июня 2019

В дополнение к принятому ответу выше, другой метод решения этой проблемы состоит в извлечении частей списка и вставке их в виде отдельных разделенных соответствующих списков в предварительно созданный POJO.

В этом примере я взял функции name() и creationDate() и поместил их в свой список в классе S3. Это позволяет Джексону читать класс S3 и получать необходимую информацию без необходимости создания дополнительного POJO для класса Bucket. Не совсем уверен, какой способ на самом деле чище или эффективнее, но это также сработало для того, что я делал.

Класс строительства S3

@Component
public class S3 {
    private ArrayList<String> bucketList;
    private ArrayList<Instant> bucketCreationDate;

    public ArrayList<Instant> getBucketCreationDate() {
        return bucketCreationDate;
    }

    public void setBucketCreationDate(ArrayList<Instant> bucketCreationDate) {
        this.bucketCreationDate = bucketCreationDate;
    }

    public ArrayList<String> getBucketList() {
        return bucketList;
    }

    public void setBucketList(ArrayList<String> bucketList) {
        this.bucketList = bucketList;
    }
}

Класс доступа

@Repository
public class S3Access implements S3Repository {

    @Autowired
    private S3 s3Instance;

    private Region region = Region.US_EAST_1;
    private S3Client s3Client = S3Client.builder().region(region).build();
    private ArrayList <String> bucketNameList = new ArrayList<>();
    private ArrayList <Instant> bucketCreationDate = new ArrayList<>();

    @Override
    public S3 listBucket() {
        ListBucketsRequest listBucketsRequest = ListBucketsRequest.builder().build();
        ListBucketsResponse listBucketsResponse = s3Client.listBuckets(listBucketsRequest);

        // Adding Bucket Names to Array List
        for (int i = 0; i < listBucketsResponse.buckets().size() ; i++) {
            bucketNameList.add(listBucketsResponse.buckets().get(i).name());
        }

        // Adding Bucket Creation Dates to Array List
        for (int i = 0; i < listBucketsResponse.buckets().size() ; i++) {
            bucketCreationDate.add(listBucketsResponse.buckets().get(i).creationDate());
        }

        // Setting the lists in the S3 Class
        s3Instance.setBucketCreationDate(bucketCreationDate);
        s3Instance.setBucketList(bucketNameList);

        return s3Instance;


Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...