我一直在尝试将 dateOfBirth 字段添加到注册表单中。我想将日期分为3个字段:日,月和年。
当我输入日期到字段时,我进入控制器当前日期和奇怪的一年 - " 3890"。
我的HTML代码:
<div class="form-group row">
<label for="confirm" class="col-sm-2 col-form-label">Date of Birth</label>
<div class="col-sm-10">
<input id="day" type="text" th:field="*{dateOfBirth.day}"/>
</div>
</div>
<div class="form-group row">
<label for="confirm" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<input id="month" type="text" th:field="*{dateOfBirth.month}"/>
</div>
</div>
<div class="form-group row">
<label for="confirm" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<input id="year" type="text" th:field="*{dateOfBirth.year}"/>
</div>
</div>
我的控制器代码:
@GetMapping(value = "/register")
public String showRegistrationForm(WebRequest request, Model model) {
ChannelDTO channelData = new ChannelDTO();
model.addAttribute("channel", channelData);
return "registration";
}
@PostMapping(value = "/register")
public ModelAndView registerUserAccount(@ModelAttribute("channel") @Valid ChannelDTO channelData, BindingResult result,
HttpServletRequest request, Errors errors, RedirectAttributes redirectAttributes) {
Channel channel = null;
if (!result.hasErrors()) {
channel = createUserAccount(channelData, result);
}
// logic...
return new ModelAndView("redirect:/register/select-interests");
}
我的ChannelDTO:
@PasswordMatches
public class ChannelDTO {
@NotNull
@NotEmpty
@Email
private String email;
@NotNull
@NotEmpty
private String name;
//@NotNull
//@NotEmpty
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date dateOfBirth;
@NotNull
@NotEmpty
private String password;
@NotNull
@NotEmpty
private String matchingPassword;
}
感谢您的帮助,谢谢。
答案 0 :(得分:0)
您正在使用原始日期类(它与java 8&n; datetime API无关): java.util.Date
文档说明了setYear:
将此Date对象的年份设置为指定值加上1900。
因此您需要在1900年之前减去年份值。 可能你可以用th:value来做,或者在控制器中你可以在逻辑部分之前减去1900年的dateOfBirth。
或者您可以使用Thymeleaf java8 datetime API模块,如下所示: Thymeleaf - Module for Java 8 Time API compatibility
如果您想在1900之前减去日期,请尝试以下方法:
@PostMapping(value = "/register")
public ModelAndView registerUserAccount(@ModelAttribute("channel") @Valid ChannelDTO channelData, BindingResult result, HttpServletRequest request, Errors errors, RedirectAttributes redirectAttributes) {
Calendar cal = Calendar.getInstance();
cal.setTime(channelData.getDateOfBirth());
cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) - 1900);
channelData.setDateOfBirth(cal.getTime());
Channel channel = null;
if (!result.hasErrors()) {
channel = createUserAccount(channelData, result);
}
//logic...
return new ModelAndView("redirect:/register/select-interests");
}
同时修改此行:
<input id="day" type="text" th:field="*{dateOfBirth.day}"/>
对此:
<input id="day" type="text" th:field="*{dateOfBirth.date}"/>
您也可以尝试不使用dateOfBirth的Date类型,而是使用Calendar。
您可以尝试两种选择:
选项1:
按原样保留ChannelDTO并修改控制器,如下所示:
@PostMapping(value = "/register")
public ModelAndView registerUserAccount(@ModelAttribute("channel") @Valid ChannelDTO channelData,
BindingResult result, HttpServletRequest request, Errors errors, RedirectAttributes redirectAttributes) {
Calendar cal = Calendar.getInstance();
cal.setTime(channelData.getDateOfBirth());
cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) - 1900);
cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) - 1);
channelData.setDateOfBirth(cal.getTime());
Channel channel = null;
if (!result.hasErrors()) {
channel = createUserAccount(channelData, result);
}
//logic...
return new ModelAndView("redirect:/register/select-interests");
}
将您的html修改为:
<div class="form-group row">
<label for="confirm" class="col-sm-2 col-form-label">Date of Birth</label>
<div class="col-sm-10">
<input id="day" type="text" th:field="*{dateOfBirth.date}" />
</div>
</div>
<div class="form-group row">
<label for="confirm" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<input id="month" type="text" th:field="*{dateOfBirth.month}" />
</div>
</div>
<div class="form-group row">
<label for="confirm" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<input id="year" type="text" th:field="*{dateOfBirth.year}" />
</div>
</div>
选项2:
创建一个新类,用于保存年,月和日值:
public class CustomDate {
public CustomDate() {
}
private int year;
private int month;
private int day;
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month -1;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
}
像这样修改ChannelDTO类:
public class ChannelDTO {
public ChannelDTO() {
}
@NotNull
@NotEmpty
@Email
private String email;
@NotNull
@NotEmpty
private String name;
//@NotNull
//@NotEmpty
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date dateOfBirth;
private CustomDate customDateOfBirth;
@NotNull
@NotEmpty
private String password;
@NotNull
@NotEmpty
private String matchingPassword;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getDateOfBirth() {
Calendar cal = Calendar.getInstance();
cal.set(customDateOfBirth.getYear(), customDateOfBirth.getMonth(), customDateOfBirth.getDay());
return cal.getTime();
}
public void setDateOfBirth(Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getMatchingPassword() {
return matchingPassword;
}
public void setMatchingPassword(String matchingPassword) {
this.matchingPassword = matchingPassword;
}
@Transient
public CustomDate getCustomDateOfBirth() {
return customDateOfBirth;
}
public void setCustomDateOfBirth(CustomDate customDateOfBirth) {
this.customDateOfBirth = customDateOfBirth;
}
}
请注意,有一个名为customDateOfBirth的新字段,customDateOfBirth的getter方法有一个@Transient注释,可防止JPA将其插入数据库。如果你想跳过它通过Jackson序列化,也可以在getter方法上放一个@JsonIgnore注释。
getDateOfBirth方法中有一个自定义逻辑,它将customDateOfBirth转换为Date类型。
像这样修改你的html:
<div class="form-group row">
<label for="confirm" class="col-sm-2 col-form-label">Date of
Birth</label>
<div class="col-sm-10">
<input id="day" type="text" th:field="*{customDateOfBirth.day}" />
</div>
</div>
<div class="form-group row">
<label for="confirm" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<input id="month" type="text" th:field="*{customDateOfBirth.month}" />
</div>
</div>
<div class="form-group row">
<label for="confirm" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<input id="year" type="text" th:field="*{customDateOfBirth.year}" />
</div>
</div>
请注意,customDateOfBirth用于html模板。