Bonjour à tous,

Je revient vers vous pour un nouveau petit soucis. J'ai donc un formulaire qui affiche tout un tas d'infos sur un objet choisis pour pouvoir le modifer/ou en créer un nouveau (c'est le même formulaire pour les deux actions). J'arrive bien à ajouter/sauvegarder l'objet après modification ou création, mais le problème vient d'une liste déroulante constituée d'objets, je n'arrive pas à récupérer la valeur de l'objet sélectionner dans la liste.

Résultat, dans la base de donnée je me retrouve avec un champs à null et ça fait foirer l'affichage après par une joli NullPointerException.

J'ai essayer pas mal de choses différentes mais y'a rien à faire, sur le net j'avais vu qu'il fallait passer par un converteur comme dans le formulaire Spring traite ça comme du simple texte et que c'est côté Java qu'il faut récupérer la valeur pour en faire l'objet désiré avant de l'insérer dans la base de donnée. Pour ça j'ai utiliser PropertyEditorSupport avec un InitBinder, mais ce dernier n'a pas l'air de fonctionner et je vois pas pourquoi, si vous pouviez m'éclairer ça serait vraiment sympa !

Voici les portions de code adéquates pour ça :

Mon éditor :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class MetaClassEditor extends PropertyEditorSupport {
 
	@Autowired
	private MetaClassService metaClassService;
 
	@Override
	public String getAsText() {
		Object obj = getValue();
 
		if (obj != null && obj instanceof MetaClass){
			System.out.println("---------- Hello ----------");
			return ((MetaClass) obj).getId().toString();
		} 
 
		System.out.println("******* Hello ******");
		return super.getAsText();
	}
 
	@Override
	public void setAsText(String idStr) throws IllegalArgumentException {
		if (idStr != null && !idStr.isEmpty() && !idStr.equals("null")) {
			MetaClass parentClass = metaClassService.getClassById(Long.valueOf(idStr));
			setValue(parentClass);
			System.out.println("---------- Good ----------");
		} else {
			System.out.println("---------- Not Good ----------");
			setValue(null);
		}
	}
}
Mon InitBinder et mon contrôlleur qui sont dans la même classe :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@InitBinder
	public void initBinder(WebDataBinder binder){
		binder.registerCustomEditor(MetaClass.class, "parentClass", new MetaClassEditor());
	}
 
@RequestMapping(value="manage/class", params="saveOrUpdateClass", method = RequestMethod.POST)
	public ModelAndView addClass(@ModelAttribute("class") MetaClass metaClass, BindingResult result){
 
		System.out.println("----- Passe ----");
		metaClass.setLastUpdateDate(new Date(System.currentTimeMillis()));
 
		metaClassService.save(metaClass);
 
		long id= metaClass.getId();
 
		ModelAndView response = new ModelAndView("redirect:/editclasses.html");
 
		response.addObject("id", id);
 
		return response;
	}
Ma page jsp correspondante (volontairement tronquée avec seulement les infos utiles, elle est longue)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<form:form action="manage/class.html" method="post" commandName="class"
	modelAttribute="class" id="formEditClasses">
	<form:select path="parentClass" id="slcParentClass" itemValue="id"
		itemLabel="name">
		<c:forEach items="${allClasses}" var="item">
			<c:choose>
				<c:when test="${item.id == showClass.parentClass.id}">
					<form:option value="${item.id}" selected="selected">
						<c:out value="${item.name}"></c:out>
					</form:option>
				</c:when>
				<c:otherwise>
					<form:option value="${item.id}">
						<c:out value="${item.name}"></c:out>
					</form:option>
				</c:otherwise>
			</c:choose>
		</c:forEach>
	</form:select>
 
	<div id="classActions">
		<p>
			<input type="image" src="<c:url value="resources/images/save.png" />"
				name="saveOrUpdateClass" id="imgSaveClass" title="Save the class"
				alt="Image save class" /> <input type="image"
				src="<c:url value="resources/images/delete.png" />"
				name="deleteClass" id="imgDeleteClass" title="Delete the class"
				alt="Image delete class" />
		</p>
	</div>
</form:form>
.

Sachant que niveau stacktrace il ne m'affiche absolument rien, hormis le NullPointerException qui intervient pour l'affichage après, pour l'insertion j'ai rien du tout, même avec un fichier log4j pour le debug :/

EDIT : Finalement j'ai trouver la solution, il m'a suffit de déclarer un constructeur dans mon editor qui reçoit mon service en paramètre et de modifier l'init binder en conséquence.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
public MetaClassEditor(MetaClassService metaClassService2) {
		this.metaClassService = metaClassService2;
	}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
@InitBinder
	public void initBinder(WebDataBinder binder){
		binder.registerCustomEditor(MetaClass.class, "parentClass", new MetaClassEditor(this.metaClassService));
	}