Получите параметры из углового запроса на публикацию в виде объектов, а не строки

#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/