[FIXED] How to receive Blob data from angular in java rest client

Issue

I created a pdf in angular, which I’ve put in a Blob object. I’m sending this Blob object, togheter with an Order object (combined in payload OrderAndBlob) to my java restclient. Though I seem unable to receive this value. I always get an error that java doesn’t understand the Blob object coming in. I get this error:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.sql.Blob` (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
 at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream)

I follow this article Cannot construct instance of – Jackson and tried to add

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")

in front of my Blob object inside the OrderAndBlob, but that just changes the error. How can I make sure the Blob object gets parsed?

Angular ts code:

  @ViewChild('pdfOrder') pdfOrder!: ElementRef;

   confirmOrder(): void {

    let DATA: any = document.body;
    html2canvas(DATA).then( async (canvas) => {
          let fileWidth = 208;
          let fileHeight = (canvas.height * fileWidth) / canvas.width;
          let PDF = new jsPDF('p', 'mm', 'a4');
          let position = 0;
          PDF.addImage(canvas, 'PNG', 0, position, fileWidth, fileHeight);
          console.log("in ts file:" + PDF);
          this.pdfBlob = PDF.output('blob');
          console.log("in ts file converted to blob:" + this.pdfBlob);

    }).then((value:void)=>{
          this.salesproductService.submitOrderedItems(this.order, this.pdfBlob);
          this.router.navigate(["/main"]);
          }
    )

   
  }

Angular service:

  public submitOrderedItems(order: Order, pdf: Blob) {
    console.log("submitting ordered items");
    const url = "http://localhost:8080/orders/add";

    console.log(pdf);
    this.orderAndBlob = new OrderAndBlob(order, pdf);

    console.log(this.orderAndBlob);
    this.http.post(url, this.orderAndBlob).subscribe(value => {});
    
    console.log("sended");
  }

Java controller + object:

@RestController
@RequestMapping("/orders")
@CrossOrigin(origins = "*", maxAge = 3600)
public class OrderController {
    @PostMapping("/add")
    @PreAuthorize("hasRole('USER')")
    public void addOrders(@RequestBody OrderAndBlob orderAndBlob) {
        System.out.println(orderAndBlob.getBlob());
        orderService.saveOrderAndLines(orderAndBlob.getOrder());
    }
}



public class OrderAndBlob {
    private Order order;
    private Blob blob;
    public Order getOrder() {
        return order;
    }
    //@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
    public Blob getBlob() {
        return blob;
    }
    
    
}

Solution

Using FormData you can do so, Please let me know if need any help

public postWithFormData(_url: string, blob: any, filename: any): Observable<any> 
{
    var formData = new FormData();
    formData.append("file", blob, filename);
    return this.httpclient.post(_url, formData, {
      reportProgress: true,
      responseType: "json"
    });
 }

Answered By – Rehan Khan

Answer Checked By – David Marino (FixeMe Volunteer)

Leave a Reply

Your email address will not be published.