SpringBoot で Vaadin 14 を使用しています。画像を Google バケットにアップロードするソフトウェアを作成しています。アップロード自体は正常に機能しますが、バケットに到達するファイルは画像ではなくなります。数週間前にコードを書きましたが、それでも機能しました。何も変わっていませんが、今はもう機能しません。InputStream を使用してバケットにアップロードしています。Vaadin アップロード コンポーネントからストリームを取得します。ここにコードがあります
vaadin コンポーネントから memoryBuffer へのアップロード
public CreateKidView(@Autowired KidService kidService) {
this.kidService = kidService;
TextField kidFirstName = new TextField("Voornaam");
TextField kidLastName = new TextField("Achternaam");
DatePicker kidBirthDate = new DatePicker("GeboorteDatum");
TextField kidMedication = new TextField("Medicatie");
MemoryBuffer memoryBuffer = new MemoryBuffer();
Upload imageUpload = new Upload(memoryBuffer);
Button button = new Button("Kind toevoegen",
buttonClickEvent -> {
saveKidAndNavigate(kidFirstName.getValue(), kidLastName.getValue(), kidBirthDate.getValue(),
kidMedication.getValue(), memoryBuffer.getInputStream());
}
);
button.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
addClassName("centered-content");
add(kidFirstName, kidLastName, kidBirthDate, kidMedication, imageUpload, button);
}
次に、入力ストリームを他のいくつかのクラスに渡します。ここに到達するまでは何もしません: contentType: "image/jpeg" を設定し、それを自分のbucketServiceに渡して入力ストリームをアップロードします。
public void addImageToPerson(Person person, String imageName, InputStream inputStream) {
String image = bucketService.uploadFileToBucket(imageName, "image/jpeg", inputStream);
......
}
@Slf4j
@Service
public class BucketService {
private final String companyName;
private final Storage storage;
@Autowired
public BucketService(@Value("${company.name}")String companyName, @Value("${gc.project.name}")String gcProjectName) {
this.companyName = companyName;
storage = StorageOptions.newBuilder().setProjectId(gcProjectName).build().getService();
}
public String uploadFileToBucket(String fileName, String contentType, InputStream inputStream) {
try {
BlobId blobId = BlobId.of(companyName, fileName);
BlobInfo blobInfo = BlobInfo.newBuilder(blobId).build();
storage.create(blobInfo, IOUtils.toByteArray(inputStream));
return fileName;
} catch (StorageException | IOException e) {
log.error("could not save image: {}", e.getMessage());
return "oops";
}
}
}
以前は完全に機能していましたが、それ以来コードは変更されていないため、Google で何かが変更されたと推測しています。試してみることができること、または変更されたことを知っている人がいるかどうか疑問に思っていました。
入力ストリーム自体が有効かどうかをテストするコードもいくつか作成しました。メモリから取得した画像を画面に表示します。
前もって感謝します :)
- 編集
さらに調査した結果、入力ストリームによって生成された byte[] が、ファイル自体によって生成された byteArray とは異なることがわかりました。
byte[] bytes = IOUtils.toByteArray(inputStream);
byte[] content = Files.readAllBytes(Paths.get("/Users/BartDuwez/Desktop/avatars-000338105915-u01ky6-t500x500.jpg"));
storage.create(blobInfo, content);
1 バイトの違いがあります: 最初のバイトです。
バイト: -40、-1、-30、...
内容: -1、-40、-1、-30、...
これがどのように機能するかについては何も知りません。明確にするために、byte[] コンテンツはバケットに画像を正しく表示します!
inputStream 内の buf をチェックすると、byte[] があり、その byte[] の内部は content byte[] と同じです。
デバッガーでこれを行う場合:
storage.create(blobInfo, ((ByteArrayInputStream) inputStream).buf);
ファイルがアップロードされて動作しますが、.buf は保護されているため、コードで使用できません。これにより、入力ストリームをバイト[]に変換するときに問題が発生しているように見えます
これで私を助けることができる何かを知っている人はいますか?