#angular #spring-boot #http-post
Вопрос:
Я создаю приложение, которое отправляет огромную угловую реактивную форму обратно в API SpringBoot по почтовому запросу. Моя проблема в том, что я могу получить параметры реакции тела в виде строки, но не в виде объекта.
Угловой
HTML
<div class="container-fluid">
<div class="form-control col-md-12">
<form class="form-group" (ngSubmit)="sendSurvey()" [formGroup]="customQuestionForm">
<div formArrayName="questionArray"
*ngFor=" let question of questionArray.controls;let i=index">
<div class="form-group" [formGroupName]="i">
<div class="form-group ">
<label>{{question.value.body}}</label>
<label name="mandatory"></label>
<textarea class="form-control" id ="{{'question ' i ' body'}}" formControlName="questionResponse"></textarea>
</div>
</div>
</div>
<button class="btn btn-primary"
style="width:80px;"
type="submit">Submit </button>
</form>
</div>
</div>
компонент.ts
@Component({
selector: 'app-reactv-account-form',
templateUrl: './reactv-account-form.component.html',
styleUrls: ['./reactv-account-form.component.css']
})
export class ReactvAccountFormComponent implements OnInit {
customQuestionForm!: FormGroup;
questionnaire!: Questionnaire
constructor(private fb : FormBuilder, private hTTPCommunicationService: HTTPCommunicationService) { }
get questionArray (): FormArray{
return <FormArray>this.customQuestionForm.get('questionArray')
}
ngOnInit(): void {
this.customQuestionForm= this.fb.group({
questionArray: this.fb.array([])
})
this.getQuestions()
}
[...] // par of ts for display
//################################## Http Communication #####################################"
getQuestions(): void{
this.hTTPCommunicationService.getQuestions()
.subscribe({
next:(questionArray:Question[])=>(this.displayQuestions(questionArray), Validators.required)
})
}
sendSurvey(){
if (this.customQuestionForm.valid){
if (this.customQuestionForm.dirty){
this.questionnaire={...this.questionnaire, ...this.customQuestionForm.value} // this array is injected from the form
// those values are set for testing
this.questionnaire.id=1
this.questionnaire.creationTimeStamp = new Date();
this.questionnaire.user_id= "MyUserId";
this.questionnaire.ownerAdvice=true;
this.questionnaire.managerAdvice=true;
this.questionnaire.finalAdvice=true;
this.questionnaire.isSubmitedForm=true
//end of testing values injection
this.hTTPCommunicationService.sendUserDemandToServer(this.questionnaire)
.subscribe({
next:()=>this.customQuestionForm.reset()
})
}
}
}
}
Весна
Класс RestController
@RestController
public class EndPointsManager {
[...] //other part of the class
@CrossOrigin(origins="http://localhost:4200/")
@RequestMapping(method=RequestMethod.POST, value="/sendSurvey")
@ResponseBody
public boolean receivingSurvey(final HttpServletRequest request,FrontEndAccessForm newSurvey) {
this.emptySurveyService.createAccessDemande(newSurvey); // new Survey parametters are all as initialisation values, not request sent ones.
return true;
}
// But if i use
//public boolean receivingSurvey(@RequestBody String fullBody) {
//i can see the sent datas
Data Objects
FrontEndAccessForm
public class FrontEndAccessForm {
int id;
LocalDateTime creationTimeStamp;
String user_id;
List<FrontEndQuestions> questionArray;
boolean ownerAdvice;
boolean managerAdvice;
boolean finalAdvice;
boolean isSubmitedForm;
public FrontEndAccessForm(List<FrontEndQuestions> questionArray,int id, LocalDateTime creationTimeStamp,String user_id,
boolean ownerAdvice, boolean managerAdvice , boolean finalAdvice, boolean isSubmitedForm
) {
super();
this.id = id;
this.creationTimeStamp = creationTimeStamp;
this.user_id = user_id;
this.questionArray = questionArray;
this.ownerAdvice = ownerAdvice;
this.managerAdvice = managerAdvice;
this.finalAdvice = finalAdvice;
this.isSubmitedForm = isSubmitedForm;
}
public FrontEndAccessForm() {
super();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public LocalDateTime getCreationTimeStamp() {
return creationTimeStamp;
}
public void setCreationTimeStamp(LocalDateTime creationTimeStamp) {
this.creationTimeStamp = creationTimeStamp;
}
public String getUser_id() {
return user_id;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
public List<FrontEndQuestions> getQuestionArray() {
return questionArray;
}
public void setQuestionArray(List<FrontEndQuestions> questionList) {
this.questionArray = questionList;
}
public boolean isOwnerAdvice() {
return ownerAdvice;
}
public void setOwnerAdvice(boolean ownerAdvice) {
this.ownerAdvice = ownerAdvice;
}
public boolean isManagerAdvice() {
return managerAdvice;
}
public void setManagerAdvice(boolean managerAdvice) {
this.managerAdvice = managerAdvice;
}
public boolean isFinalAdvice() {
return finalAdvice;
}
public void setFinalAdvice(boolean finalAdvice) {
this.finalAdvice = finalAdvice;
}
public boolean isSubmitedForm() {
return isSubmitedForm;
}
public void setSubmitedForm(boolean isSubmitedForm) {
this.isSubmitedForm = isSubmitedForm;
}
}
FrontEndQuestions
public class FrontEndQuestions {
int id;
String body;
boolean mandatoryStatus;
String questionResponse;
public FrontEndQuestions() {
super();
}
public FrontEndQuestions(String body, int id, boolean mandatoryStatus, String questionResponse) {
super();
this.id = id;
this.body = body;
this.mandatoryStatus = mandatoryStatus;
this.questionResponse = questionResponse;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public boolean isMandatoryStatus() {
return mandatoryStatus;
}
public void setMandatoryStatus(boolean mandatoryStatus) {
this.mandatoryStatus = mandatoryStatus;
}
public String getQuestionResponse() {
return questionResponse;
}
public void setQuestionResponse(String questionResponse) {
this.questionResponse = questionResponse;
}
}
Any idea where iam wrong ?
Solution EDIT
In case it can help anybody, i found the solution, i had multiple mistakes:
In the ts file, i wasen’t returning the data as JSON, i edited as below inside my HttpCommunicationService:
getQuestions():Observable<Question[]>{
const url="http://localhost:8080/completeSurvey"
return this.httpModule.get<Question[]>(url)
.pipe(
tap(data =>console.log(' ############### getQuestions:' JSON.stringify(data)))
)
}
Spring mistakes:
i had to change my backend function too as bellow
@CrossOrigin(origins="http://localhost:4200/")
@RequestMapping(value="/sendSurvey")
@PostMapping(
consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE}
)
public void receivingSurvey(@RequestBody FrontEndAccessForm newAccessDemand) {
this.emptySurveyService.createAccessDemande(newAccessDemand);
}
Вот ссылка на блог, который спас мой день
https://www.appsdeveloperblog.com/postmapping-requestbody-spring-mvc/