У меня есть Status Code 400 в интерфейсе, когда я пытаюсь отправить запрос POST с Angular 5 на Spring Boot Rest Controller.
@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-------------------------------
}
@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;
}
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);
}
}
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;
}
export class PrestatairesTypeModel
{
id:any;
designation:any;
}
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.info("Added");
this.getAllTypes();
this.modelType = data;
}, err=>{
console.info("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=>{
}, ()=>{
});
}
}
<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">×</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>
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);
}
}
я не сделал. я отправляю запрос из формы. запрос работает нормально, когда я удаляю эту строку кода formData.append ('prestatairesTypes', model.prestatairesTypes); в служебном файле. но я получаю нулевые данные в базе данных внешнего ключа
Я просто тестирую api с почтальоном. это дает мне ту же ошибку 400 (неверный запрос)
Не могли бы вы обновить код запроса, который вам сгенерировал почтальон?
POST / prestataires HTTP / 1.1 Хост: localhost: 8080 Content-Type: multipart / form-data; border = ---- WebKitFormBoundary7MA4YWxkTrZu0gW Cache-Control: no-cache Postman-Token: 3dd2ce54-e4cf-daed-bbb7-a22f627ce9a7 ------ WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-Disposition: form name = "nom" sdsd ------ WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name = "email" sdsd ------ WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name = "теле"
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 = "файл"; filename = "Jordanie.jpg" Content-Type: image / jpeg
------ WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name = "photo" ------ WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name = "prestatairesTypes" {"id": 1, "обозначение": "ff", "coproprietes": null} ------ WebKitFormBoundary7MA4YWxkTrZu0gW--
Для этого вопроса не было необходимости добавлять код внешнего интерфейса. Бланка почтальона, который вы отправили, было достаточно. Вы забыли добавить исключение серверной части, это было бы гораздо полезнее.




If you set the file name to multipartFile, it should work.
Проблема в том, что @RequestParam("multipartFile") MultipartFile file не получает файл, потому что нет поля формы с именем multipartFile. Это то, что вы настроили с помощью @RequestParam.
Это фрагмент почтальона, который вы можете использовать. Проверить последний параметр.
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--
при отправке этого запроса на бэкэнд у меня была следующая ошибка: {"timestamp": 1539867360299, "status": 500, "error": "Internal Server Error", "exception": "org.springframework.web.multipart.MultipartException" , "message": "Текущий запрос не является составным", "path": "/ prestataires"}
Вы предоставляете файл, который действительно существует? Покажите нам исключение серверной части.
это бэкэнд-заголовок ошибки: org.springframework.web.multipart.MultipartException: текущий запрос не является составным запросом
Отметьте этот ответ stackoverflow.com/a/42016651/5473627. Он также получает MultipartException, потому что он включил заголовок Content-Type. Убери это.
после этого ответа у меня возникла ошибка кода состояния 400: {"timestamp": 1539868805973, "status": 400, "error": "Bad Request", "exception": "org.springframework.validation.BindException", " ошибки »: [{« коды »: [« typeMismatch.prestataires.prestatairesTypes »,« typeMismatch.prestatairesTypes »,« typeMismatch.smart.syndic.entities.PrestatairesTypes »,« typeMismatch »],« arguments »: [
Удалите код @ManyToOne @JoinColumn(name = "ID_PRESTATAIRES_TYPES") private PrestatairesTypes prestatairesTypes; ... Это уже другая проблема для другого вопроса :)
{"коды": ["prestataires.prestatairesTypes", "prestatairesTypes"], "arguments": null, "defaultMessage": "prestatairesTypes", "code": "prestatairesTypes"}], "defaultMessage": "Не удалось преобразовать свойство значение типа java.lang.String для требуемого типа smart.syndic.entities.PrestatairesTypes для
свойство prestatairesTypes; вложенное исключение - org.springframework.core.convert.ConversionFailedException: не удалось преобразовать тип [java.lang.String] в тип [java.lang.Long] для значения '{\ "id \": 1, \ "обозначение \ ": \" ff \ ", \" coproprietes \ ": null} '; вложенное исключение - java.lang.NumberFormatException: для входной строки: \ "{\" id \ ": 1, \" обозначение \ ": \" ff \ ", \" coproprietes \ ": null} \" ", "objectName": "prestataires", "field": "prestatairesTypes", "rejectedValue": "{\" id \ ": 1, \" обозначение \ ": \" ff \ ", \" coproprietes \ ": null} ",
эта ошибка находится в почтальоне: "bindingFailure": true, "code": "typeMismatch"}], "message": "Ошибка проверки объекта = 'prestataires'. Количество ошибок: 1", "path": "/ prestataires" }
Покажите исключение, которое вы получили в своей консоли ide, плз
Невозможно отправить объект, содержащий внешний ключ, - это мой главный вопрос в этом посте
у меня нет ошибки в Backend. ошибка 400. Я думаю, что запрос не доходит до серверной части, потому что он неправильно сформирован
Кто-нибудь может ответить на этот вопрос? пожалуйста
Вы пытались отправить запрос от почтальона?