java - 如何从角度接收日期(弹簧)类型的requestParam
问题描述
我是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>
- 这里是角度组件代码:
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 =>{
});
}
- 这里是角度服务代码
public search(search){
return this.http.get(this.url+"?beforeAdmission="+search.beforeAdmission+"&afterAdmission="+search.afterAdmission
+"&beforePay="+search.beforePay+"&afterPay="+search.afterPay,{headers:this.headers});
}```
- 这里是弹簧控制器代码
@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的一些解决方案,但对我没有任何帮助,
解决方案
In your Angular service, you are sending the dates of your Search
as their toString()
representation. But in your Spring controller, you are expecting them to be in "dd/mm/yyyy" format. Spring cannot parse your those date strings into a Date
, hence the IllegalArgumentException
.
You can format the JS dates into "dd/mm/yyyy" in your Angular service. For example using a simple method like:
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}`;
}
Or use a date library like https://date-fns.org/ for more robust formatting.
Then use the formatDate
method in your service:
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);
}
Finally, you need to set the pattern
of @DateTimeFormat
to be correct (mm
is minute of hour).
@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);
}
I would also suggest using java.time.LocalDate
over java.util.Date
.
推荐阅读
- angular - 如何在没有互联网连接的情况下使用传单地图(离线模式),最好在 Angular 中使用
- r - stat_compare_means 比较不在 x 轴上的组
- swift - 可变 3 列 NavigationView SwiftUI
- javascript - Vue.js axios 方法挂载未定义;v-for 不起作用 - Wordpress 页面
- class - SwiftUI 使用 Core Data 在类中进行计算
- python - Python BLE 发现所有 UUID 特征
- image - 在 Flutter 中本地缓存 base64 图像
- javascript - 有人能告诉我为什么这段代码不叫我那个函数吗?
- mysql - Docker 卷数据被存储两次?
- visual-studio-code - 如何在 VS Code 中更改我的字体,因为显然这给了我错误的输出