我有两个实体 Environnment 和 ServeurApplicatif ,它们具有oneToMany关系。我有一个动态表单,每次用户想要将ServeurApplicatif与Environnement实体关联时,都会添加一个新表单。提交预期结果时,环境实体和与之关联的ServeurApplicatif实体的持久性。
但是在我的情况下,每当我尝试提交表单时,我都会收到 400 http错误:您的请求在语法上不正确。
这里是动态添加子实体相关表单的javascript代码:
<script type="text/javascript">
$(document).ready(function() {
var index = ${fn:length(env.serveurApplicatifs)};
console.log("index value :"+index);
$("#addServ").off("click").on("click",function() {
$(this).before(function() {
var html = '<div id="serveurApplicatifs'+index+'.wrapper" style="display: none;">';
html += '<input type="hidden" id="serveurApplicatifs'+index+'.idserv" name="serveurApplicatifs['+index+'].idserv" ></input>';
html += '<p><strong>Serveur Applicatif 1 : </strong></p>';
html += '<div class="form-group"><label for="serveurApplicatifs'+index+'.port">Port :</label><input class ="form-control" type="text" id="serveurApplicatifs'+index+'.port" name="serveurApplicatifs['+index+'].port" ></input></div>';
html += '<div class="form-group"><label for="serveurApplicatifs'+index+'.compte">Compte :</label><input class ="form-control" type="text" id="serveurApplicatifs'+index+'.compte" name="serveurApplicatifs['+index+'].compte" ></input></div>';
html += '<div class="form-group"><label for="serveurApplicatifs'+index+'.pwd">Mot de passe :</label><input class ="form-control" type="text" id="serveurApplicatifs'+index+'.pwd" name="serveurApplicatifs['+index+'].pwd" ></input></div>';
html += '<div class="form-group"><label for="serveurApplicatifs'+index+'.adresse">Adresse :</label><input class ="form-control" type="text" id="serveurApplicatifs'+index+'.adresse" name="serveurApplicatifs['+index+'].adresse" ></input></div>';
html += '<a href="#" class="serveurApplicatifs.remove" data-index="'+index+'">Supprimer</a>';
html += "</div>";
return html;
});
$("#serveurApplicatifs"+index+"\\.wrapper").show();
index++;
return false;
});
$("a.serveurApplicatifs.remove").off("click").on("click",function() {
var index2remove = $(this).data("index");
$("#serveurApplicatifs"+index2remove+"\\.wrapper").hide();
$("#serveurApplicatifs"+index2remove+"\\.remove").val("1");
return false;
})
jsp中的Spring表单标记:
<c:url value="/envs/save" var="saveUrl"/>
<form:form action="${ saveUrl }" method="POST" modelAttribute="env">
<div class="form-group">
<form:input type="hidden" class="form-control" id="idEnv" placeholder="id" path="idEnv"></form:input><span id="star">*</span>
</div>
<!-- ------------- -->
<div class="form-group">
<label for="nom">Nom</label>
<form:input type="text" class="form-control" id="nom" placeholder="Nom" path="nom"></form:input><span>*</span>
<form:errors path="nom" cssClass="error"></form:errors>
</div>
<div class="form-group">
<label for="plateforme">Platforme</label>
<form:input type="text" class="form-control" id="plateform" placeholder="Plateforme" path="platforme"></form:input>
<form:errors path="platforme" cssClass="error"></form:errors>
</div>
<div class="form-group">
<label for="typologie">Typologie</label>
<form:input type="text" class="form-control" id="typologie" placeholder="Typologie" path="typologie"></form:input>
<form:errors path="typologie" cssClass="error"></form:errors>
</div>
<div class="form-group">
<label for="bd">Base de donnée</label>
<form:input type="text" class="form-control" id="bd" placeholder="Bdd" path="bd"></form:input>
<form:errors path="bd" cssClass="error"></form:errors>
</div>
<div class="form-group">
<label for="version">Version</label>
<form:input type="text" class="form-control" id="version" placeholder="Version" path="version"></form:input>
<form:errors path="version" cssClass="error"></form:errors>
</div>
<div class="form-group">
<label for="machine_bd">Serveur de base de données</label>
<form:input type="text" class="form-control" id="machine_bd" placeholder="Machine Bdd" path="machineBd"></form:input>
<form:errors path="machineBd" cssClass="error"></form:errors>
</div>
<div class="form-group">
<label for="port_bd">Port Base de données</label>
<form:input type="text" class="form-control" id="port_bd" placeholder="Port bdd" path="portBd"></form:input>
<form:errors path="portBd" cssClass="error"></form:errors>
</div>
<div class="form-group">
<label for="version_bd">Version de base de données</label>
<form:input type="text" class="form-control" id="version_bd" placeholder="Version bdd" path="versionBd"></form:input>
<form:errors path="versionBd" cssClass="error"></form:errors>
</div>
<div class="form-group">
<label for="type_bd">Type de base de données</label>
<form:input type="text" class="form-control" id="type_bd" placeholder="Type bdd" path="typeBd"></form:input>
<form:errors path="typeBd" cssClass="error"></form:errors>
</div>
<div class="form-group">
<label for="depart">Environnement de départ</label>
<form:radiobutton value ="1" id="depart" path="depart" label="Oui"></form:radiobutton>
<form:radiobutton value ="0" id="depart" path="depart" label="Non"></form:radiobutton>
<form:errors path="depart" cssClass="error"></form:errors>
</div>
<div class="form-group">
<label for="repert">Repert</label>
<form:input type="text" class="form-control" id="repert" placeholder="Repert" path="repert"></form:input>
<form:errors path="repert" cssClass="error"></form:errors>
</div>
<div class="form-group">
<label for="port_ftp">Port FTP</label>
<form:input type="text" class="form-control" id="port_ftp" placeholder="Port FTP" path="portFtp"></form:input>
<form:errors path="portFtp" cssClass="error"></form:errors>
</div>
<div class="form-group">
<label for="exclu">Exclu</label>
<form:radiobutton value ="1" id="exclu" path="exclu" label="Oui"></form:radiobutton>
<form:radiobutton value ="0" id="exclu" path="exclu" label="Non"></form:radiobutton>
<form:errors path="exclu" cssClass="error"></form:errors>
</div>
<div class="form-group">
<label for="envsPrec">Précedent</label>
<form:select class="form-control" id="envsPrec" path="environnements2" items="${ envsPrecSuiv }" itemLabel="nom" itemValue="idEnv"/>
<form:errors path="environnements2" cssClass="error"></form:errors>
</div>
<div class="form-group">
<label for="envsSuiv">Suivant</label>
<form:select class="form-control" id="envsSuiv" path="environnements1" items="${ envsPrecSuiv }" itemLabel="nom" itemValue="idEnv"/>
<form:errors path="environnements1" cssClass="error"></form:errors>
</div>
<c:forEach varStatus="loop" var="serveurApplicatifs" items="${ env.serveurApplicatifs }">
<c:choose>
<c:when test="${env.serveurApplicatifs[loop.index].remove eq 1 }">
<div id="serveurApplicatifs${loop.index }.wrapper" style="display: none;">
</c:when>
<c:otherwise>
<div id="serveurApplicatifs${ loop.index }.wrapper">
</c:otherwise>
</c:choose>
<div class="form-group">
<form:input type="hidden" class="form-control" id="idApp" path="env.serveurApplicatifs[${loop.index}].idserv"></form:input>
</div>
<div class="form-group">
<label for="portApp">Port serveur applicatif</label>
<form:input type="text" class="form-control" id="portApp" placeholder="Port" path="env.serveurApplicatifs[${loop.index}].port"></form:input>
</div>
<div class="form-group">
<label for="compteApp">Compte serveur applicatif</label>
<form:input type="text" class="form-control" id="compteApp" placeholder="Compte" path="env.serveurApplicatifs[${loop.index}].compte"></form:input>
</div>
<div class="form-group">
<label for="pwdApp">Mot de passe serveur applicatif</label>
<form:input type="text" class="form-control" id="pwdApp" placeholder="Mot de passe" path="env.serveurApplicatifs[${loop.index}].pwd"></form:input>
</div>
<div class="form-group">
<label for="adresseApp">Adresse serveur applicatif</label>
<form:input type="text" class="form-control" id="adresseApp" placeholder="Adresse" path="env.serveurApplicatifs[${loop.index}].adresse"></form:input>
</div>
<c:choose>
<c:when test="${serveurApplicatifs[loop.index].remove eq 1}"><c:set var="hiddenValue" value="1"></c:set></c:when>
<c:otherwise><c:set var="hiddenValue" value="0"></c:set> </c:otherwise>
</c:choose>
<form:hidden path="serveurApplicatifs[${loop.index}].remove" value="${hiddenValue}"/>
<a href="#" class="serveurApplicatifs.remove" data-index="${loop.index}">Supprimer</a>
</div>
</c:forEach>
<button type="button" class="btn btn-default" id="addServ">Ajouter Un Serveur d'application</button>
<button type="submit" class="btn btn-default" value="Save">Submit</button>
</form:form>
Environnement实体类:
@Entity
@NamedQuery(name="Environnement.findAll", query="SELECT e FROM Environnement e")
public class Environnement implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id_env")
private int idEnv;
private String bd;
private int depart;
private int exclu;
@Column(name="machine_bd")
private String machineBd;
@Column(name="mdp_bdd")
private String mdpBdd;
private String nom;
private String platforme;
@Column(name="port_bd")
private int portBd;
@Column(name="port_ftp")
private int portFtp;
private String repert;
@Column(name="type_bd")
private String typeBd;
private String typologie;
@Column(name="utilisateur_bdd")
private String utilisateurBdd;
private String version;
@Column(name="version_bd")
private String versionBd;
//bi-directional many-to-many association to Composant
@ManyToMany
@JoinTable(
name="env_comp"
, joinColumns={
@JoinColumn(name="id_env")
}
, inverseJoinColumns={
@JoinColumn(name="id_comp")
}
)
private List<Composant> composants;
//bi-directional many-to-many association to Environnement
@LazyCollection(LazyCollectionOption.FALSE)
@ManyToMany
@JoinTable(
name="lien_environnement"
, joinColumns={
@JoinColumn(name="id_env_suiv")
}
, inverseJoinColumns={
@JoinColumn(name="id_env_prec")
}
)
private List<Environnement> environnements1;
//bi-directional many-to-many association to Environnement
@LazyCollection(LazyCollectionOption.FALSE)
@ManyToMany
@JoinTable(
name="lien_environnement"
, joinColumns={
@JoinColumn(name="id_env_prec")
}
, inverseJoinColumns={
@JoinColumn(name="id_env_suiv")
}
)
private List<Environnement> environnements2;
//bi-directional many-to-one association to ServeurApplicatif
@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(mappedBy="environnement")
private List<ServeurApplicatif> serveurApplicatifs;
ServeurApplicatif实体类:
@Entity
@Table(name="serveur_applicatif")
@NamedQuery(name="ServeurApplicatif.findAll", query="SELECT s FROM ServeurApplicatif s")
public class ServeurApplicatif implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int idserv;
private String adresse;
private String compte;
private int port;
private String pwd;
@Transient
private Integer remove;
//bi-directional many-to-one association to Environnement
@ManyToOne
@JoinColumn(name="id_env")
private Environnement environnement;
用于保存实体的控制器方法:
@RequestMapping(value="/envs/save",method=RequestMethod.POST)
public ModelAndView saveEnvironnement(@ModelAttribute(value="env")Environnement env) {
//Environnement envFinal = this.envService.validate(env);
this.envService.gererServeur(env);
/*for (ServeurApplicatif servApp : env.getServeurApplicatifs()) {
}*/
envService.saveOrUpdate(env);
for (ServeurApplicatif servApp : env.getServeurApplicatifs()) {
servAppService.saveOrUpdate(servApp);
}
return new ModelAndView("redirect:/envs");
}
EnvironnementService中的gererServeur方法classe:
@Override
public List<ServeurApplicatif> gererServeur(Environnement env) {
// TODO Auto-generated method stub
List<ServeurApplicatif> serveurRemoved = new ArrayList<ServeurApplicatif>();
if(env.getServeurApplicatifs() != null) {
for (Iterator<ServeurApplicatif> iterator = serveurRemoved.iterator(); iterator
.hasNext();) {
ServeurApplicatif serveurApplicatif = iterator.next();
if(serveurApplicatif.getRemove() == 1) {
serveurRemoved.add(serveurApplicatif);
iterator.remove();
}
else {
serveurApplicatif.setEnvironnement(env);
}
}
}
return serveurRemoved;
}
请注意,我使用此处显示的解决方案来管理动态表单: Spring 3 MVC: one-to-many within a dynamic form (add/remove on create/update)
修改:
我尝试在文档就绪函数之外声明行var index = ${fn:length(env.serveurApplicatifs)};
但它没有帮助,console.log在加载表单时返回0但是每次我按下按钮添加新表单时都会增加对于 ServeurApplicatif ,发送到服务器的表单数据如下:
idEnv:0
nom:
platforme:
typologie:
bd:
version:
machineBd:
portBd:0
versionBd:
typeBd:
depart:0
repert:
portFtp:0
exclu:0
_environnements2:1
_environnements1:1
serveurApplicatifs[0].idserv:
serveurApplicatifs[0].port:14523
serveurApplicatifs[0].compte:test
serveurApplicatifs[0].pwd:test
serveurApplicatifs[0].adresse:test
serveurApplicatifs[1].idserv:
serveurApplicatifs[1].port:14523
serveurApplicatifs[1].compte:test
serveurApplicatifs[1].pwd:test
serveurApplicatifs[1].adresse:test
_csrf:2d856fad-16f3-4ae4-a254-47922a695c17
您会注意到,与idenv不同,idserv不会自动填充。这两个ID都是DB中的自动增量字段,其他空白字段可以为空,因此不存在问题。
提前致谢。
答案 0 :(得分:0)
我发现了什么问题。
基本上 idserv 未获得默认值0 ,以便
spring可以处理对服务器的请求,当调用saveOrUpdate时,hibernate可以在 Environnment实体旁边插入 ServeurApplicatif实体,所以我在javascript中添加了value="0"
代码负责为即时创建ServeurApplicatifs的表单输入,现在它按预期工作。