0

I have a Status Code 400in the frontend when i try to send a POST request with Angular 5 to Spring Boot Rest Controller.

Here is the Entity :

@Entity
public class Prestataires implements Serializable 
{
@Id @GeneratedValue
private Long id;
private String nom;
private String email;
private String tele;
private String fax;
private String rib;
private String adresse;
private String taches;
private String photo;

@Lob
private byte[] file;

 @ManyToOne
 @JoinColumn(name="ID_PRESTATAIRES_TYPES")
 private PrestatairesTypes prestatairesTypes;

//--------------Getters and Setters------------------------
//--------------Constructors-------------------------------

}

Here is the Second Entity:

@Entity
public class PrestatairesTypes implements Serializable 
{
 @Id @GeneratedValue
 private Long id;

 private String designation;

 //-------------------Constructors----------------
 //--------------Getters and Setters-------------------

 //---------------------OneToMany---------------------

 @OneToMany(mappedBy="prestatairesTypes")
 private Collection<Prestataires> prestataires; 

 }

Here is the RestController :

 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.web.bind.annotation.CrossOrigin;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.multipart.MultipartFile;

 import smart.syndic.dao.PrestatairesRepository;
 import smart.syndic.entities.Prestataires;

 @RestController
 @CrossOrigin("*")
 public class PrestatairesRestController 
 {
  @Autowired
  private PrestatairesRepository repository;

 @RequestMapping(value="/prestataires", 
        method=RequestMethod.POST)
 public Prestataires addVilles(Prestataires p,
        @RequestParam("multipartFile") MultipartFile file)
 {
    byte[] rawFile = null;
    try{

        rawFile = file.getBytes();
    }catch(Exception e){
        e.printStackTrace();
    }

    p.setFile(rawFile);

    return repository.save(p);              
 }

 }

Here is The Model Prestataires in TypeScript :

 export class PrestatairesModel
 {
  id:any;
  nom:any;
  email:any;
  tele:any;
  fax:any;
  rib:any;
  adresse:any;
  taches:any;
  photo:any;
  file:any;

  prestatairesTypes:any;

  }

Here is the model PrestatairesTypes in TypeScript:

export class PrestatairesTypeModel
{
 id:any;
 designation:any;
}

Here is the Angular Controller in TypeScript :

 import { Component, OnInit } from '@angular/core';
 import {PrestatairesService} from "../../services/prestataires.service";
 import {PrestatairesTypeModel} from "../../modeles/prestatairesType.model";
 import {PrestatairesModel} from "../../modeles/prestataires.model";


 @Component({
 selector: 'app-ajouter-prestataires',
 templateUrl: './ajouter-prestataires.component.html',
 styleUrls: ['./ajouter-prestataires.component.css']
 })
 export class AjouterPrestatairesComponent implements OnInit {

 nom:any = null;
 email:any = null;
 tele:any = null;
 fax:any = null;
 rib:any = null;
 adresse:any = null;
 taches:any = null;
 photo:any = null;

 selectTypes:any;

 typePrestataire:any;

 tousLesPrestatairesTypes:any;

 modelType:any;

 imageURL:string = "../assets/images/MeG.jpg";

 fileToUpload:File = null;

  modelPrestataires:any;


  constructor(private service:PrestatairesService) { }

  ngOnInit()
  {
     this.getAllTypes();

  }

  handleFileInput(file:any)
  {
    this.fileToUpload = <File>file.target.files[0];
    let reader = new FileReader();
    reader.onload = (event:any)=>{
    this.imageURL = event.target.result;
  }

  reader.readAsDataURL(this.fileToUpload);

  }

  getAllTypes()
  {
    this.service.getAllTypes()
    .subscribe(data=>{
      this.tousLesPrestatairesTypes = data;
    }, err=>{

    }, ()=>{

    })
 }

  ajouterTypesPrestataires()
 {
   this.modelType = new PrestatairesTypeModel();
   this.modelType.designation = this.typePrestataire;

   this.service.ajouterType(this.modelType)
    .subscribe(data=>{

    console.log("Added");
    this.getAllTypes();
    this.modelType = data;

   }, err=>{
    console.log("Error");
  }, ()=>{

  })

}

 ajouterPrestataires()
 {

  this.modelPrestataires = new PrestatairesModel();
  this.modelPrestataires.nom = this.nom;
  this.modelPrestataires.email = this.email;
  this.modelPrestataires.tele = this.tele;
  this.modelPrestataires.fax = this.fax;
  this.modelPrestataires.rib = this.rib;
  this.modelPrestataires.adresse = this.adresse;
  this.modelPrestataires.taches = this.taches;
  this.modelPrestataires.photo = this.photo;
  this.modelPrestataires.file = this.fileToUpload;

  this.service.getOneType(this.selectTypes)
    .subscribe(data=>{
      this.modelPrestataires.prestatairesTypes = data;
    }, err=>{

    }, ()=>{
      this.service.uploadFile(this.modelPrestataires)
        .subscribe(data=>{

          this.modelPrestataires = data;

        }, err=>{

        }, ()=>{

        });
    });




   }

 getOneType(id:any)
 {
   this.service.getOneType(id)
    .subscribe(data=>{
    this.modelType = data;
  }, err=>{

  }, ()=>{

  });

 }

 }

Here is the View :

<div class="right_col" role="main">
 <div class="">
  <div class="page-title">
    <div class="title_left">
    <h3>Ajouter Prestataires</h3>
  </div>


  </div>
<div class="clearfix"></div>

<div class="row">
  <div class="col-md-12 col-sm-12 col-xs-12">
    <div class="x_panel">
      <div class="x_title">
        <h2>Nouveau Prestataire</h2>
        <ul class="nav navbar-right panel_toolbox">
          <li><a class="collapse-link"><i class="fa fa-chevron-up"></i></a>
          </li>
          <li class="dropdown">
            <a href="#" class="dropdown-toggle" data-toggle="dropdown" 
  role="button" aria-expanded="false"><i class="fa fa-wrench"></i></a>
            <ul class="dropdown-menu" role="menu">
              <li><a routerLink="/prestataires">Retour Prestataires</a>
              </li>
            </ul>
          </li>
          <li><a class="close-link"><i class="fa fa-close"></i></a>
          </li>
        </ul>
        <div class="clearfix"></div>
      </div>
      <div class="x_content">

        <div class="x_content">




            <div id="containerAjouterPrestataires">

            </div>

            <form class="form-horizontal form-label-left">

              <div class="form-group">
                <label class="control-label col-md-3 col-sm-3 col-xs- 
        12">Raison Social/Nom<span class="required">*</span>
                </label>
                <div class="col-md-6 col-sm-6 col-xs-12">
                  <input [(ngModel)]="nom" name="nom" type="text" required 
 class="form-control col-md-7 col-xs-12">
                </div>
              </div>

              <div class="form-group">
                <label class="control-label col-md-3 col-sm-3 col-xs- 
  12">Email<span class="required">*</span>
                </label>
                <div class="col-md-6 col-sm-6 col-xs-12">
                  <input [(ngModel)]="email" name="email" type="email" 
  required class="form-control col-md-7 col-xs-12">
                </div>
              </div>

              <div class="form-group">
                <label class="control-label col-md-3 col-sm-3 col-xs- 
        12">Téléphone<span class="required">*</span></label>
                <div class="col-md-6 col-sm-6 col-xs-12">
                  <input [(ngModel)]="tele" name="tele" class="form-control 
      col-md-7 col-xs-12" type="text" required>
                </div>
              </div>

              <div class="form-group">
                <label class="control-label col-md-3 col-sm-3 col-xs- 
    12">Fax<span class="required">*</span></label>
                <div class="col-md-6 col-sm-6 col-xs-12">
                  <input [(ngModel)]="fax" name="fax" class="form-control 
     col-md-7 col-xs-12" type="text" required>
                </div>
              </div>

              <div class="form-group">
                <label class="control-label col-md-3 col-sm-3 col-xs- 
   12">RIB<span class="required">*</span></label>
                <div class="col-md-6 col-sm-6 col-xs-12">
                  <input [(ngModel)]="rib" name="rib" class="form-control 
     col-md-7 col-xs-12" type="text" required>
                </div>
              </div>

              <div class="form-group">
                <label class="control-label col-md-3 col-sm-3 col-xs- 
   12">Type<span class="required">*</span></label>
                <div class="col-md-6 col-sm-6 col-xs-12">

                  <div class="input-group">
                    <select class="form-control" name="selectTypes" 
 [(ngModel)]="selectTypes">
                      <option selected="selected" *ngFor="let s of 
  tousLesPrestatairesTypes" [value]="s.id" >
                        {{s.designation}}
                      </option>
                    </select>
                    <span class="input-group-btn">
                    <!-- Button trigger modal -->
                    <button type="button" class="btn btn-default" data- 
  toggle="modal" data-target="#myModal">
                      Ajouter Type
                    </button>
                  </span>
                  </div>
                </div>
              </div>

              <div class="form-group">
                <label class="control-label col-md-3 col-sm-3 col-xs- 
 12">Adresse<span class="required">*</span>
                </label>
                <div class="col-md-6 col-sm-6 col-xs-12">
                  <textarea [(ngModel)]="adresse" name="adresse" 
 class="form-control" rows="3" placeholder="Adresse"></textarea>
                </div>
              </div>

              <div class="form-group">
                <label class="control-label col-md-3 col-sm-3 col-xs- 
 12">Tâches<span class="required">*</span>
                </label>
                <div class="col-md-6 col-sm-6 col-xs-12">
                  <textarea [(ngModel)]="taches" name="taches" class="form- 
  control" rows="3" placeholder="Tâches"></textarea>
                </div>
              </div>

              <!-- Modal -->
              <div class="modal fade" id="myModal" tabindex="-1" 
  role="dialog" aria-labelledby="myModalLabel">
                <div class="modal-dialog modal-lg" role="document">
                  <div class="modal-content">
                    <div class="modal-header">
                      <button type="button" class="close" data- 
  dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span> 
  </button>
                      <h4 class="modal-title" id="myModalLabel">Ajouter Type 
   Prestataire</h4>
                    </div>
                    <div class="modal-body">
                      <form class="form-horizontal form-label-left">

                        <div id="containerType">

                        </div>

                        <div class="form-group">
                          <label class="control-label col-md-3 col-sm-3 col- 
 xs-12">Nouveau Type<span class="required">*</span></label>
                          <div class="col-md-6 col-sm-6 col-xs-12">
                            <input [(ngModel)]="typePrestataire" 
 name="typePrestataire" class="form-control col-md-7 col-xs-12" type="text" 
 required>
                          </div>
                          <button type="button" class="btn btn-success" 
 (click)="ajouterTypesPrestataires()">Ajouter</button>

                        </div>

                      </form>
                    </div>
                    <div class="modal-footer">
                      <button type="button" class="btn btn-danger" data- 
 dismiss="modal" id="fermer">Fermer</button>
                    </div>
                  </div>
                </div>
              </div>
              <!--  /modal -->

              <div class="form-group">
                <label class="control-label col-md-3 col-sm-3 col-xs- 
  12">Photo/Logo<span class="required">*</span></label>
                <div class="col-md-6 col-sm-6 col-xs-12">
                  <input name="multipartFile" class="form-control col-md-7 
 col-xs-12"
                         type="file" required="required"
                         (change)="handleFileInput($event)">
                </div>
              </div>

              <div class="form-group">
                <label class="control-label col-md-3 col-sm-3 col-xs- 
  12">Image Preview</label>
                <div class="col-md-6 col-sm-6 col-xs-12">
                  <img class="imagePrestataires" [src]="imageURL">
                </div>
              </div>

              <div class="form-group">
                <div class="col-md-6 col-sm-6 col-xs-12 col-md-offset-3">
                  <button class="btn btn-warning" 
 type="reset">Vider</button>
                  <button type="button" class="btn btn-success" 
 (click)="ajouterPrestataires()">Ajouter</button>
                </div>
              </div>
            </form>

          </div>
          </div>

        </div>
      </div>
    </div>
  </div>
 </div>

Here is the Service.ts

import {Injectable} from "@angular/core";
import {HttpClient, HttpEvent, HttpHeaders, HttpParams, HttpRequest} from 
"@angular/common/http";

 @Injectable()
 export class PrestatairesService
  {
   host:string = "http://localhost:8080/";
   constructor(private http:HttpClient)
  {

  }

getAllTypes()
{
  return this.http.get(this.host + "prestatairesTypes");
}

 ajouterType(model:any)
 {
   return this.http.post(this.host + "prestatairesTypes", model);
 }

 getOneType(id:any)
 {
   return this.http.get(this.host + "prestatairesTypes/" + id);
 }

 ajouterPrestataires(model:any)
 {
   return this.http.post(this.host + "prestataires", model);
 }

 uploadFile(model:any)
 {

 let formData = new FormData();
 formData.append('multipartFile', model.file);
 formData.append('nom', model.nom);
 formData.append('email', model.email);
 formData.append('rib', model.rib);
 formData.append('taches', model.taches);
 formData.append('fax', model.fax);
  formData.append('adresse', model.adresse);

 // This is the line that cause the Error of status code 400
 // What to do here to send the request correctly
 formData.append('prestatairesTypes', model.prestatairesTypes);
 formData.append('tele', model.tele);

 let params = new HttpParams();

 const options = {
  params: params,
  reportProgress: true,
 };

 const req = new HttpRequest('POST', this.host+"prestataires", formData, 
  options);
 return this.http.request(req);
  }
 }
mariuss
  • 1,177
  • 2
  • 14
  • 30
beyyato abdellah
  • 127
  • 1
  • 2
  • 15
  • Did you try sending the request from postman? – Pranjal Gore Oct 17 '18 at 20:22
  • i didn't. i am sending the request from a Form. the request work fine when i remove this line of code formData.append('prestatairesTypes', model.prestatairesTypes); in the service file. but i get a null data in the database of the foreign key – beyyato abdellah Oct 17 '18 at 20:39
  • i just test the api with postman. it's give me the same Error 400(Bad Request) – beyyato abdellah Oct 17 '18 at 21:48
  • Could you update code for the request that postman generates for you? – Pranjal Gore Oct 18 '18 at 02:55
  • POST /prestataires HTTP/1.1 Host: localhost:8080 Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW Cache-Control: no-cache Postman-Token: 3dd2ce54-e4cf-daed-bbb7-a22f627ce9a7 ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="nom" sdsd ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="email" sdsd ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="tele" – beyyato abdellah Oct 18 '18 at 10:14
  • sdsd ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="rib" sdsd ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="fax" sdsd ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="adresse" sdsd ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="taches" dsdsd ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="file"; filename="Jordanie.jpg" Content-Type: image/jpeg – beyyato abdellah Oct 18 '18 at 10:14
  • ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="photo" ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="prestatairesTypes" {"id":1, "designation":"ff", "coproprietes":null} ------WebKitFormBoundary7MA4YWxkTrZu0gW-- – beyyato abdellah Oct 18 '18 at 10:14
  • For this question it was unnecessary to add the frontend code. The postman form you sent was enough. You forgot to add the backend exception, that would've been much more helpfull. – Yoshua Nahar Oct 18 '18 at 12:23

1 Answers1

0

If you set the file name to multipartFile, it should work.

The problem is that the @RequestParam("multipartFile") MultipartFile file isn't receiving the file, because there is no form field with the name multipartFile. That is what you configured with @RequestParam.

This is a postman snippet that you can use. Check the last parameter.

POST /prestataires HTTP/1.1
Host: localhost:8080
Cache-Control: no-cache
Postman-Token: 809c9cd4-8b66-43e6-939c-1f2a554ca982
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="nom"

NOM
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="email"

EMAIL
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="tele"

TELE
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="fax"

FAX
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="rib"

RIB
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="adresse"

ADRESSE
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="taches"

TACHES
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="photo"

PHOTO
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="multipartFile"; filename="demo.txt"
Content-Type: text/plain


------WebKitFormBoundary7MA4YWxkTrZu0gW--
Yoshua Nahar
  • 1,304
  • 11
  • 28
  • while sending this request to backend i have the following Error: { "timestamp": 1539867360299, "status": 500, "error": "Internal Server Error", "exception": "org.springframework.web.multipart.MultipartException", "message": "Current request is not a multipart request", "path": "/prestataires" } – beyyato abdellah Oct 18 '18 at 12:55
  • Are you providing a file that actually exists? Show us the backend exception. – Yoshua Nahar Oct 18 '18 at 13:01
  • this is the backend title of the Error : org.springframework.web.multipart.MultipartException: Current request is not a multipart request – beyyato abdellah Oct 18 '18 at 13:04
  • Check this answer https://stackoverflow.com/a/42016651/5473627. He is also getting a MultipartException, because he included a Content-Type header. Remove it. – Yoshua Nahar Oct 18 '18 at 13:10
  • after following this answer i have an Error of status code 400 :{ "timestamp": 1539868805973, "status": 400, "error": "Bad Request", "exception": "org.springframework.validation.BindException", "errors": [ { "codes": [ "typeMismatch.prestataires.prestatairesTypes", "typeMismatch.prestatairesTypes", "typeMismatch.smart.syndic.entities.PrestatairesTypes", "typeMismatch" ], "arguments": [ – beyyato abdellah Oct 18 '18 at 13:23
  • Remove the `@ManyToOne @JoinColumn(name="ID_PRESTATAIRES_TYPES") private PrestatairesTypes prestatairesTypes;` code... That is a different problem for another question :) – Yoshua Nahar Oct 18 '18 at 13:24
  • { "codes": [ "prestataires.prestatairesTypes", "prestatairesTypes" ], "arguments": null, "defaultMessage": "prestatairesTypes", "code": "prestatairesTypes" } ], "defaultMessage": "Failed to convert property value of type 'java.lang.String' to required type 'smart.syndic.entities.PrestatairesTypes' for – beyyato abdellah Oct 18 '18 at 13:24
  • property 'prestatairesTypes'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.lang.Long] for value '{\"id\":1, \"designation\":\"ff\", \"coproprietes\":null}'; nested exception is java.lang.NumberFormatException: For input string: \"{\"id\":1,\"designation\":\"ff\",\"coproprietes\":null}\"", "objectName": "prestataires", "field": "prestatairesTypes", "rejectedValue": "{\"id\":1, \"designation\":\"ff\", \"coproprietes\":null}", – beyyato abdellah Oct 18 '18 at 13:24
  • this Error is in postman : "bindingFailure": true, "code": "typeMismatch" } ], "message": "Validation failed for object='prestataires'. Error count: 1", "path": "/prestataires" } – beyyato abdellah Oct 18 '18 at 13:31
  • Show the exception you receive in your ide console plz – Yoshua Nahar Oct 18 '18 at 13:32
  • unable to POST an object that contain foreign key is my main question in this post – beyyato abdellah Oct 18 '18 at 13:35
  • i have no Error in Backend. the error is 400. i think the request does not reach the backend because it's not well formed – beyyato abdellah Oct 18 '18 at 13:35
  • Can anyone answer this question ? please – beyyato abdellah Oct 19 '18 at 20:22