[@Controller][Validator] Injecter un service depuis un validator
Bonsoir à tous,
Je suis entrain de galérer sur l'injection d'un service depuis une classe validator :
Voici ma classe service :
Code:
1 2 3 4 5 6 7 8 9 10 11 12
|
@Service("PersonService")
public class PersonServiceImpl implements PersonService {
@Autowired
private PersonDao dao;
public void setDao(PersonDao dao) {
this.dao = dao;
}
... |
Voici mon contrôleur :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
@Controller
@SessionAttributes("person")
public class PersonController {
@Autowired
private PersonService service;
public void setService(PersonService service) {
this.service = service;
}
@RequestMapping(value = "/form.html", method = RequestMethod.POST)
public String submit(@ModelAttribute("person")Person person, BindingResult result, SessionStatus status) {
new PersonValidator().validate(person, result);
if (result.hasErrors()) {
return "form";
} else {
service.saveOrUpdate(person);
status.setComplete();
return "redirect:list.html";
}
} |
Je voudrais tester si la personne existe déjà dans la base de données avant de la rajouter :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
public class PersonValidator implements Validator {
@Autowired
private PersonService service;
public void setService(PersonService service) {
this.service = service;
}
public boolean supports(Class clazz) {
return false;
}
public void validate(Object object, Errors errors) {
Person p = (Person) object;
System.out.println("dans le validate : "+p.getNom());
if(service.userExists(p.getNom())){
errors.rejectValue("nom","errors.required", null,"Username already taken.");
}
} |
J'ai un java.lang.NullPointerException sur la variable service quand j'invoque la méthode service.userExists(p.getNom()) de la couche :cry:
Pourtant l'objet p n'est pas a null, j'ai vérifié il est bien remplit par l'interface.
Ce qui est bizarre est que si je désactive cette ligne, la méthode service.saveOrUpdate(person); du contrôleur s'exécute parfaitement => le contrôleur arrive bien a injecter le service et pas le validator !
Voici la stack error :
Code:
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
|
GRAVE: "Servlet.service()" pour la servlet spring a g�n�r� une exception
java.lang.NullPointerException
at spring.tutorial.web.PersonValidator.validate(PersonValidator.java:36)
at spring.tutorial.web.PersonController.submit(PersonController.java:88)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:160)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:245)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:874)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:808)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:476)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:441)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:75)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Unknown Source) |
j'ai rajouté cette ligne dans le spring-config.xml
Code:
1 2 3 4 5
|
<bean id="configurationLoader" class="org.springmodules.validation.bean.conf.loader.annotation.AnnotationBeanValidationConfigurationLoader" />
<bean id="validator"
class="org.springmodules.validation.bean.BeanValidator"
p:configurationLoader-ref="configurationLoader" /> |
Auriez-vous une idée pourquoi je n'arrive pas à injecter le service dans ma classe Validator ?
Merci par avance de votre aide.
injecter le validator dans le controlleur
Merci pour vos réponses,
Pour répondre à JeitEmgie, j'ai bien séparé les couches et je pouvais pas faire la vérification de l'unicité après la validation du contenu propre par ce que je pourrais plus retourner une erreur ! a moins que tu as une solution à me proposer ;)
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
@RequestMapping(value = "/form.html", method = RequestMethod.POST)
public String submit(@ModelAttribute("person")Person person, BindingResult result, SessionStatus status) {
new PersonValidator().validate(person, result);
// a ce niveau je peux vérifier l'unicité mais je ne peux plus remplir result.hasErrors()
if (result.hasErrors()) {
return "form";
} else {
service.saveOrUpdate(person);
status.setComplete();
return "redirect:list.html";
}
} |
mais je voudrais rebondir sur la remarque de Hikage :
Citation:
L'autre moyen est de te faire injecter le validator dans le controlleur, dans ce cas la, l'injection du service sera réalisée dans le validator aussi
Justement, comment injecter le validator dans le controlleur ?
Les exemples que j'ai trouvé appellent tous le validateur en passant par un
Code:
1 2
|
new PersonValidator().validate(person, result); |
Merci