弹簧靴 + Thymeleaf; th:object+复选框 "arbitrarily" 中的字段给出错误
Springs Boot + Thymeleaf; th:object+field in checkbox "arbitrarily" giving errors
经过 15 小时的尝试和恐惧,我决定与全世界分享我的问题,因为坦率地说,我不知道如何解决我的问题了:
我创建了一个自定义表单供用户选中复选框并按下保存按钮:
这是相关代码的片段:
<form th:action="@{/profile}" action="/profile" th:object="${profileModel}" method="POST">
<div class="row" style="margin-left: 5px;"><h4>Select</h4></div>
<div class="row">
<!-- Barbell -->
<section class="panel panel-default panel-equipment col-md-3">
<header class="panel-heading panel-heading-profileform">
<h3 class="panel-title"><b>Barbell</b></h3>
</header>
<div class="col-md-12">
<div><input type="checkbox" th:field="*{equipment.barbellLight}" th:value="1"> Light</input></div>
<div><input type="checkbox" th:field="*{equipment.barbellMedium}" th:value="1"> Medium</input></div>
<div><input type="checkbox" th:field="*{equipment.barbellHeavy}" th:value="1"> Heavy</input></div>
</div>
</section>
</div>
</div>
</form>
我的控制器:
要求:
@RequestMapping(value = "/profilestage", method=RequestMethod.POST)
public String updateProfileStage(@ModelAttribute ProfileModel profileModel, Model model){
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String username = auth.getName();
model.addAttribute("signedin", true);
model.addAttribute("username", username.substring(0, 1).toUpperCase() + username.substring(1));
UserEntity user = userService.findByUsername(username);
ProfileEntity profile = user.getProfile();
model.addAttribute("profileModel", ModelEntityConvertor.profileEntityToModel(profile));
return "profile_new";
}
这不是控制器的全部,但据您所知,我已经非常彻底地调试了所有这些代码,并且 th:object
中使用的 profileModel 是从不为 null 并且始终设置所有必填字段(在我的例子中都是 0)。
表单正在发送到此控制器:
@RequestMapping(value = "/profile", method=RequestMethod.POST)
public String updateProfile(@ModelAttribute ProfileModel profileModel, Model model){
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String username = auth.getName();
UserEntity user = userService.findByUsername(username);
ProfileEntity profile = user.getProfile();
profile.setEquipment(ModelEntityConvertor.equipmentModelToEntity(profileModel.getEquipment(), profile.getEquipment()));
profileService.updateProfile(profile);
return this.getProfile(model);
}
每当我的应用程序决定不工作时,就永远不会到达该控制器,但只要到达它,它就会像一个魅力一样工作并且完全按照它应该的方式工作。
我正在努力解决的一个大问题是,所有这些 偶尔 有效.. 一分钟我 运行 代码,没问题。然后我重新 运行 完全相同的代码,尝试与另一个用户一起执行此操作,或两者都执行此操作,并在单击 save
后显示 spring 的默认错误页面。
任何地方都没有提供错误信息...
我试过:
- 清理项目
- 关闭日食
- 完全重建项目
- 在 chrome 的开发者模式下工作(我总是这样做,css 中的任何更改都会显示)
- 添加 spring.template.cache: false 和 spring.thymeleaf.cache: false 属性
老实说,我不明白自己做错了什么,非常感谢您的帮助 =)
提前感谢您阅读我的文字墙,并对后者表示歉意。
如果需要更多我的代码,我会马不停蹄地在这里。
1) 在您的第一个控制器块中将 method=RequestMethod.POST
更改为 method=RequestMethod.GET
。
Further background on GET vs POST(OP 不需要,但对于未来的读者)
2) 在您的记录器中将此设置为 DEBUG:org.springframework.web
和 org.spring.web.context
还可以进一步了解哪些页面被调用。
3) 添加一个 BindingResult
到你的方法签名来默认你的原语为零。 (请参阅评论中 OP 的注释。)
经过 15 小时的尝试和恐惧,我决定与全世界分享我的问题,因为坦率地说,我不知道如何解决我的问题了:
我创建了一个自定义表单供用户选中复选框并按下保存按钮: 这是相关代码的片段:
<form th:action="@{/profile}" action="/profile" th:object="${profileModel}" method="POST">
<div class="row" style="margin-left: 5px;"><h4>Select</h4></div>
<div class="row">
<!-- Barbell -->
<section class="panel panel-default panel-equipment col-md-3">
<header class="panel-heading panel-heading-profileform">
<h3 class="panel-title"><b>Barbell</b></h3>
</header>
<div class="col-md-12">
<div><input type="checkbox" th:field="*{equipment.barbellLight}" th:value="1"> Light</input></div>
<div><input type="checkbox" th:field="*{equipment.barbellMedium}" th:value="1"> Medium</input></div>
<div><input type="checkbox" th:field="*{equipment.barbellHeavy}" th:value="1"> Heavy</input></div>
</div>
</section>
</div>
</div>
</form>
我的控制器: 要求:
@RequestMapping(value = "/profilestage", method=RequestMethod.POST)
public String updateProfileStage(@ModelAttribute ProfileModel profileModel, Model model){
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String username = auth.getName();
model.addAttribute("signedin", true);
model.addAttribute("username", username.substring(0, 1).toUpperCase() + username.substring(1));
UserEntity user = userService.findByUsername(username);
ProfileEntity profile = user.getProfile();
model.addAttribute("profileModel", ModelEntityConvertor.profileEntityToModel(profile));
return "profile_new";
}
这不是控制器的全部,但据您所知,我已经非常彻底地调试了所有这些代码,并且 th:object
中使用的 profileModel 是从不为 null 并且始终设置所有必填字段(在我的例子中都是 0)。
表单正在发送到此控制器:
@RequestMapping(value = "/profile", method=RequestMethod.POST)
public String updateProfile(@ModelAttribute ProfileModel profileModel, Model model){
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String username = auth.getName();
UserEntity user = userService.findByUsername(username);
ProfileEntity profile = user.getProfile();
profile.setEquipment(ModelEntityConvertor.equipmentModelToEntity(profileModel.getEquipment(), profile.getEquipment()));
profileService.updateProfile(profile);
return this.getProfile(model);
}
每当我的应用程序决定不工作时,就永远不会到达该控制器,但只要到达它,它就会像一个魅力一样工作并且完全按照它应该的方式工作。
我正在努力解决的一个大问题是,所有这些 偶尔 有效.. 一分钟我 运行 代码,没问题。然后我重新 运行 完全相同的代码,尝试与另一个用户一起执行此操作,或两者都执行此操作,并在单击 save
后显示 spring 的默认错误页面。
任何地方都没有提供错误信息...
我试过:
- 清理项目
- 关闭日食
- 完全重建项目
- 在 chrome 的开发者模式下工作(我总是这样做,css 中的任何更改都会显示)
- 添加 spring.template.cache: false 和 spring.thymeleaf.cache: false 属性
老实说,我不明白自己做错了什么,非常感谢您的帮助 =)
提前感谢您阅读我的文字墙,并对后者表示歉意。 如果需要更多我的代码,我会马不停蹄地在这里。
1) 在您的第一个控制器块中将 method=RequestMethod.POST
更改为 method=RequestMethod.GET
。
Further background on GET vs POST(OP 不需要,但对于未来的读者)
2) 在您的记录器中将此设置为 DEBUG:org.springframework.web
和 org.spring.web.context
还可以进一步了解哪些页面被调用。
3) 添加一个 BindingResult
到你的方法签名来默认你的原语为零。 (请参阅评论中 OP 的注释。)