[SOLVED] Cannot save BLOB to database by using Spring Boot REST service

Issue

I try to send a Json object from Front-End that contains a BLOB variable:

imageToBlob(file).then(result =>{

              const imageData={blobData: result} //JSON DATA
                   
              axios.post('http://localhost:8080/saveImage', imageData)
                        .then();
                })

When i log result, browser prints:

Blob {size: 67386, type: 'image/png'}
size: 67386
type: "image/png"
[[Prototype]]: Blob

When i try to save it to MySQL database i get this error in Spring:

[nio-8080-exec-9] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `[B` from Object value (token `JsonToken.START_OBJECT`); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `[B` from Object value (token `JsonToken.START_OBJECT`)<EOL> at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 13] (through reference chain: com.example.pictureprojecttestbackend.entity.Picture["blobData"])]

The entity:

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class Picture {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    Integer id;

    @Lob
    byte[] blobData;
}

POST request:

@RestController
public class PictureController {

    @Autowired
    PictureRepository pictureRepository;

    @PostMapping(value = "/saveImage", consumes = "application/json")
    public void addImage(@RequestBody Picture picture){

        pictureRepository.save(picture);
    }
}

What am i doing wrong? Do i send wrong Json structure or is the problem about the entity?

Solution

A file is an array of bytes which normally can not be converted easily into a JSON. This is what you try to do and it fails during this conversion.

You should better send the file with content-type "multipart/form-data"

Try the following

@Lob
@Type(type = "org.hibernate.type.ImageType")
byte[] blobData;

And then

    @PostMapping(value = "/saveImage")
    public void addImage(@RequestParam("file") MultipartFile file){

      Picture picture = new Picture();
      picture.setBlobData(file.getBytes());

      pictureRepository.save(picture);
    }

And then adjust your frontend

imageToBlob(file).then(result =>{

              var file = result;
              var formData = new FormData();
              formData.append("file", file);
                    
              axios.post('http://localhost:8080/saveImage', formData,  
                { headers: { 'Content-Type': 'multipart/form-data' } });
                    .then();
    });

Answered By – Panagiotis Bougioukos

Answer Checked By – Dawn Plyler (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published.