是否可以将Spring控制器请求参数绑定到具有多个构造函数的对象?



我有@RestController与以下映射:

@GetMapping(value = "/periods"})
public PeriodInfoDto get(DateRange dateRange)

DateRange有三个构造函数:

public class DateRange {
@DateTimeFormat(iso=DateTimeFormat.ISO.DATE)
private YearMonth start;    
@DateTimeFormat(iso=DateTimeFormat.ISO.DATE)
private YearMonth end;
public DateRange(YearMonth start, YearMonth end) {
this.start = start;
this.end = end;
}

public DateRange(YearMonth end, Period period) {            
this(end.minus(period.minusMonths(1)), end);
}

当客户端发送请求时,报告以下异常:

. lang。IllegalStateException:没有primary或单一public为类找到构造函数daterange -没有默认值构造函数在org.springframework.beans.BeanUtils.getResolvableConstructor (BeanUtils.java: 250)~ (spring-beans-5.3.5.jar 5.3.5):

DateRange只有一个主构造函数DateRange(YearMonth, YearMonth)。另一个构造函数调用this。

客户端传入一个完整的日期字符串,如20121-01-01作为结束/开始日期请求参数,但我只关心月份和年份。

是否有一种方法告诉Spring在绑定请求时使用DateRange(YearMonth start, YearMonth end)?

堆栈跟踪表明Spring需要一个所谓的主构造函数。对于Java,这意味着可以使用单个构造函数。当你有2时,这个机制失效了。

您可以通过使用YearMonthPeriod删除构造函数并将其移动到工厂方法并使用该方法来代替构造函数来解决此问题。

public class DateRange {
private YearMonth start;    
private YearMonth end;
public DateRange(YearMonth start, YearMonth end) {
this.start = start;
this.end = end;
}

public static DateRange of(YearMonth end, Period period) {
return new DateRange(end.minus(period.minusMonths(1)), end);            
}
}

使用2021-09格式时Spring将自动使用YearMonthFormatter(从Spring 4.2开始可用)从/转换为YearMonth,而不是完整的日期。这样你就不需要@DateTimeFormat注释了。

最新更新