как получить параметр запроса типа date (spring) из angular

#java #angular #spring #spring-boot #spring-mvc

#java #angular #spring #весенняя загрузка #spring-mvc

Вопрос:

я новичок в angular и spring, я пытаюсь отправить запрос get с некоторыми параметрами даты, но я продолжаю получать ошибку..

  • вот html-код:
 <div class="form-row">
              <div class="form-group col-md-3">
                <label for="beforeAdmission">Avant l'Admission</label>
                <input type="text"
                   placeholder="Datepicker"
                   class="form-control"
                   id="beforeAdmission"
                   name="beforeAdmission" 
                   bsDatepicker
                   [bsConfig]="{ dateInputFormat: 'dd/mm/yyyy' }"
                   [(bsValue)]="search.beforeAdmission"
                   >
              </div>
              <div class="form-group col-md-3">
                <label for="afterAdmission">Après l'Admission</label>
                <input type="text"
                   placeholder="Datepicker"
                   class="form-control"
                   id="afterAdmission"
                   name="afterAdmission" 
                   bsDatepicker
                   [bsConfig]="{ dateInputFormat: 'dd/mm/yyyy' }"
                   [(bsValue)]="search.afterAdmission"
                   >
              </div>
              <div class="form-group col-md-3">
                <label for="beforePay">Avant Paiement</label>
                <input type="text"
                   placeholder="Datepicker"
                   class="form-control"
                   id="beforePay"
                   name="beforePay" 
                   bsDatepicker
                   [bsConfig]="{ dateInputFormat: 'dd/mm/yyyy' }"
                   [(bsValue)]="search.beforePay"
                   >
              </div>
              <div class="form-group col-md-3">
                <label for="afterPay">Après Paiement</label>
                <input type="text"
                   placeholder="Datepicker"
                   class="form-control"
                   id="afterPay"
                   name="afterPay" 
                   bsDatepicker
                   [bsConfig]="{ dateInputFormat: 'dd/mm/yyyy' }"
                   [(bsValue)]="search.afterPay"
                   >
              </div>
             </div>

  
  • вот код компонента angular:
 export interface Search {
    beforeAdmission:Date,
    afterAdmission : Date,
    beforePay : Date,
    afterPay : Date
}
search : Search = {
        beforeAdmission:new Date(this.d.getFullYear()   5, this.d.getMonth(), this.d.getDate()),
        afterAdmission : new Date(this.d.getFullYear() - 20 , this.d.getMonth(), this.d.getDate()),
        beforePay : new Date(this.d.getFullYear()   5 , this.d.getMonth(), this.d.getDate()),
        afterPay :  new Date(this.d.getFullYear() - 20 , this.d.getMonth(), this.d.getDate())
}

onSearch(){

        this.service.search(this.search).subscribe(res =>{
            this.cheques = res;
        },err =>{
        
        });
    }
  
  • вот код службы angular
 public search(search){
    return this.http.get(this.url "?beforeAdmission=" search.beforeAdmission "amp;afterAdmission=" search.afterAdmission
                             "amp;beforePay=" search.beforePay "amp;afterPay=" search.afterPay,{headers:this.headers});
    }```

  
  • вот код контроллера Spring
 @GetMapping("/cheques")
    public Page<ChequeOrEffet> getAll(@RequestParam(name="beforeAdmission",defaultValue = "01/01/1950")@DateTimeFormat(pattern = "dd/mm/yyyy",iso=ISO.DATE)Date beforeAdmission
                                    ,@RequestParam(name="afterAdmission",defaultValue = "01/01/2050") @DateTimeFormat(pattern = "dd/mm/yyyy",iso=ISO.DATE) Date  afterAdmission
                                    ,@RequestParam(name="beforePay",defaultValue = "01/01/1950") @DateTimeFormat(pattern = "dd/mm/yyyy",iso=ISO.DATE) Date beforePay
                                    ,@RequestParam(name="afterPay",defaultValue = "01/01/2050") @DateTimeFormat(pattern = "dd/mm/yyyy",iso=ISO.DATE) Date afterPay) {
        
        System.out.println("xx");
        return service.seach((Date)beforeAdmission, (Date)afterAdmission, (Date)beforePay, (Date)afterPay);
    }
                                    
  
  • и это ошибка, которую я продолжаю получать:
 2020-08-31 01:50:45.158  WARN 35616 --- [nio-8080-exec-7] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.util.Date'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@org.springframework.web.bind.annotation.RequestParam @org.springframework.format.annotation.DateTimeFormat java.util.Date] for value 'Sun Aug 31 2025 00:00:00 GMT 0000 (Coordinated Universal Time)'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [Sun Aug 31 2025 00:00:00 GMT 0000 (Coordinated Universal Time)]]
  

ps: я уже пробовал некоторые решения из stackoverflow, но у меня ничего не получалось,

Комментарии:

1. Судя по журналам, похоже, что вы отправляете даты JS как свои toString() , а не в ожидаемом шаблоне, который вы определили в @DateTimeFormat . Пожалуйста, поделитесь своим сервисом Angular и кодом компонента.

2. @drumonii я отредактировал код и добавил компонент angular service спасибо за ваше замечание

Ответ №1:

В вашей службе Angular вы отправляете свои даты Search в качестве их toString() представления. Но в вашем контроллере Spring вы ожидаете, что они будут в формате «дд / мм / гггг». Spring не может разобрать ваши эти строки даты в Date , следовательно IllegalArgumentException .

Вы можете отформатировать даты JS в «дд / мм / гггг» в своем сервисе Angular. Например, используя простой метод, такой как:

 formatDate(date: Date): string {
  const day = date.getDate() < 10 ? `0${date.getDate()}` : date.getDate()   '';
  const month = date.getMonth()   1 < 10 ? `0${date.getMonth()   1}` : (date.getMonth()   1)   '';
  const year = date.getFullYear()   '';
  return `${day}/${month}/${year}`;
}
  

Или используйте библиотеку дат, такую какhttps://date-fns.org / для более надежного форматирования.

Затем используйте formatDate метод в вашем сервисе:

 public search(search) {
  const params = new HttpParams()
    .set('beforeAdmission', formatDate(search.beforeAdmission))
    .set('afterAdmission', formatDate(search.afterAdmission))
    .set('beforePay', formatDate(search.beforePay))
    .set('afterPay', formatDate(search.afterPay));

  const options = {
    params,
    headers: this.headers
  };
  return this.http.get(this.url, options);
}
  

Наконец, вам нужно правильно указать pattern of @DateTimeFormat ( mm это минута часа).

 @GetMapping("/cheques")
public ResponseEntity<String> getAll(
            @RequestParam(name = "beforeAdmission", defaultValue = "01/01/1950") @DateTimeFormat(pattern = "dd/MM/yyyy") Date beforeAdmission,
            @RequestParam(name = "afterAdmission", defaultValue = "01/01/2050") @DateTimeFormat(pattern = "dd/MM/yyyy") Date afterAdmission,
            @RequestParam(name = "beforePay", defaultValue = "01/01/1950") @DateTimeFormat(pattern = "dd/MM/yyyy") Date beforePay,
            @RequestParam(name = "afterPay", defaultValue = "01/01/2050") @DateTimeFormat(pattern = "dd/MM/yyyy") Date afterPay) {
        
        System.out.println("xx");
        return service.seach((Date) beforeAdmission, (Date) afterAdmission, (Date) beforePay, (Date) afterPay);
    }
  

Я бы также предложил использовать java.time.LocalDate over java.util.Date .