thymeleaf 和 spring-boot 丢失的复杂对象
Posted
技术标签:
【中文标题】thymeleaf 和 spring-boot 丢失的复杂对象【英文标题】:Complex object lost in from with thymeleaf and spring-boot 【发布时间】:2017-03-12 07:39:14 【问题描述】:我有一个内部有嵌套复杂对象的对象:
public class MonitoringSystem
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
private String url;
private String username;
private String password;
@Transient
private String passwordConfirm;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name ="anonymization_id")
private Anonymization anonymization;
当我创建一个新对象或编辑一个现有对象时,我想保留我的匿名对象。为此,我尝试将其保存在 <input type="hidden">
中,就像我保留我的身份一样。
控制器:
@Controller
public class MonitoringSystemController
// some Code
@RequestMapping("monitoringsystem/edit/id")
public String edit(@PathVariable Long id, Model model)
model.addAttribute("monitoringsystem", monitoringSystemRepository.findOne(id));
return "monitoringsystem/form";
@RequestMapping("/monitoringsystem/new")
public String newMonitoringSystem(Model model)
model.addAttribute("monitoringsystem", new MonitoringSystem());
return "monitoringsystem/form";
@RequestMapping(value = "/monitoringsystem/save", method = RequestMethod.POST)
public String save(MonitoringSystem monitoringSystem)
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
User user = userRepository.findByUsername(auth.getName());
long id = user.getCloudProvider().getId();
anonymizationRepository.save(monitoringSystem.getAnonymization());
// more code
表格:
<form class="form-horizontal" th:modelAttribute="monitoringsystem"
th:object="$monitoringsystem" th:action="@/monitoringsystem/save" method="post">
<input type="hidden" th:field="*id"/>
<input type="hidden" th:field="*anonymization"/>
<fieldset>
<legend>New Monitoring-System</legend>
<div class="form-group">
<label class="col-md-4 control-label" for="textinput">Systemname</label>
<div class="col-md-5">
<input th:field="*name" class="form-control input-md" type="text"/>
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label" for="textinput">URL</label>
<div class="col-md-5">
<input th:field="*url" class="form-control input-md" type="text"/>
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label" for="textinput">Username</label>
<div class="col-md-5">
<input th:field="*username" class="form-control input-md" type="text"/>
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label" for="textinput">Password</label>
<div class="col-md-5">
<input th:field="*password" class="form-control input-md" type="password"/>
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label" for="textinput">Confirm Password</label>
<div class="col-md-5">
<input th:field="*passwordConfirm" class="form-control input-md" type="password"/>
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label" for="singlebutton"></label>
<div class="col-md-4">
<a th:href="@/monitoringsystem" class="btn btn-default btn-small">Cancel</a>
<button id="singlebutton" name="singlebutton" class="btn btn-primary btn-small">
Submit
</button>
</div>
</div>
</fieldset>
</form>
不幸的是,这不起作用。当我尝试使用monitoringSystem.getAnonymization()
在保存方法中获取匿名对象时,我得到了Nullpointerexception
。所以我猜这个对象没有正确存储在隐藏字段中。如何正确传递对象,使其在创建或编辑过程中不会丢失?
【问题讨论】:
你在MonitoringSystem
构造函数中实例化Anonymization
吗?在newMonitoringSystem
-Method 中,如果您没有在构造函数中创建Anonymization
,则为空
是的,它在构造函数中实例化:public MonitoringSystem() this.setAnonymization(new Anonymization());
【参考方案1】:
我现在以不同的方式解决了我的问题。我离开了这个隐藏的字段并将我的对象存储在一个会话中。在保存方法中,将它们从会话中拉出并再次将其添加到我的监视系统对象中。这可以完美运行,并且不会丢失任何数据。
此外,它更节省,因为用户可以轻松操作隐藏字段。
但感谢您的帮助。
【讨论】:
【参考方案2】:您将整个对象绑定到该字段。应该是
<input type="hidden" th:field="*anonymization.id"/>
【讨论】:
这可行,但我必须绑定每个字段: 我的对象已传递,但没有来自对象中其他字段的所有数据,例如 anonymizeHostName 等。如果有可能传递整个对象而不关心每个字段,那就太好了.有选择吗? 您仍然可以保留您的MonitoringSystem
对象。即使添加所有字段,Spring Data JPA 也会抱怨分离的Anonymization
对象。但这应该用CascadeType.MERGE
解决。总结一下:为隐藏字段绑定anonymization.id
-> 获取monitoringSystem
实例并保存。
我测试过了。如果我只添加 id 我的对象被保存但所有其他字段都具有默认值。如果我在输入中添加 id 和所有其他字段,我的对象将按原样保存(包含所有现有数据)。顺便说一句:我的对象中已经有CascadingType.ALL
以上是关于thymeleaf 和 spring-boot 丢失的复杂对象的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 spring-boot 和 thymeleaf 设置标准 i18n 语言环境?
Spring-Boot + Spring-MVC + Thymeleaf + Apache Tiles