[EMF] Spring 3.0 MVC data binding and validation [message #514823] |
Tue, 16 February 2010 18:14 |
|
Hi,
I was wondering if anyone is using EMF models with Spring MVC web applications? It appears that it is possible to use the spring's data binding if the EMF model has public constructors. I am wondering what approach to take on model validation. I have two options: using JSR 303 and declarative model validation or annotating the model with OCL invariant constraints and use dynamic templates and the generated model validator, wrapping it into spring validator.
What would you suggest as approach for model validation?
Please share your experience if you have used EMF models with Spring MVC.
Thanks
|
|
|
Re: [EMF] Spring 3.0 MVC data binding and validation [message #515591 is a reply to message #514823] |
Fri, 19 February 2010 13:45 |
|
Here is my solution that I'd like to share with the forum:
1. In the Spring MVC context I've fined two validators as follows:
<bean id="jsr303validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
<bean id="validator" class=" ... EMFModelValidator" />
2. The annotation driven MVC context is configured to use the custom EMFModelValidator:
<mvc:annotation-driven validator="validator" />
3. The implementation of the EMFModelValidator will validate with the injected JSR303 validator, if such is available at runtime, and then it will use the EMF's Diagnostician to perform the EMF based model validation. Below is sample for such custom EMFModelValidator:
public class EMFModelValidator implements Validator {
@Autowired
private Validator jsr303validator;
@Override
public boolean supports(Class<?> clazz) {
return EObject.class.isAssignableFrom(clazz);
}
@Override
public void validate(Object target, Errors errors) {
if (jsr303validator!=null) {
jsr303validator.validate(target, errors);
}
EObject eObject = (EObject) target;
Map<Object, Object> context = new HashMap<Object, Object>();
context.put(SubstitutionLabelProvider.class,
new SubstitutionLabelProvider() {
@Override
public String getObjectLabel(EObject eObject) {
return eObject.eClass().getName();
}
.......
});
BasicDiagnostic diagnostic = Diagnostician.INSTANCE.createDefaultDiagnostic(eObject);
Diagnostician.INSTANCE.validate(eObject, diagnostic, context);
if (diagnostic.getSeverity() != Diagnostic.OK) {
for (Diagnostic child : diagnostic.getChildren()) {
String errorCode = MessageFormat.format("{0}.{1}",eObject.eClass().getEPackage().getName(), eObject.eClass().getName());
errors.reject(errorCode, new Object[] {eObject}, child.getMessage());
}
}
}
Finally I it is soo simple to use this composition of JSR303 and EMF validator in your Spring MVC application - you just use the @Valid annotation on the controller's mapping, like I do here:
@RequestMapping(method=RequestMethod.POST)
public String create(@Valid Subscriber subscriber, BindingResult result) {
if (result.hasErrors()) {
return "subscriber/create";
}
dao.persist(subscriber);
return "redirect:subscriber/" + subscriber.getId();
}
Hope someone will find this useful.
|
|
|
Re: [EMF] Spring 3.0 MVC data binding and validation [message #515609 is a reply to message #515591] |
Fri, 19 February 2010 14:05 |
Ed Merks Messages: 33140 Registered: July 2009 |
Senior Member |
|
|
Assen,
That's cool. Thanks so much for sharing your solution!
Assen Sharlandjiev wrote:
> Here is my solution that I'd like to share with the forum:
>
> 1. In the Spring MVC context I've fined two validators as follows:
>
>
> <bean id="jsr303validator"
> class=" org.springframework.validation.beanvalidation.LocalValidator FactoryBean "
> />
> <bean id="validator" class=" ... EMFModelValidator" />
>
>
> 2. The annotation driven MVC context is configured to use the custom
> EMFModelValidator:
>
>
> <mvc:annotation-driven validator="validator" />
>
>
> 3. The implementation of the EMFModelValidator will validate with the
> injected JSR303 validator, if such is available at runtime, and then
> it will use the EMF's Diagnostician to perform the EMF based model
> validation. Below is sample for such custom EMFModelValidator:
>
>
> public class EMFModelValidator implements Validator {
>
> @Autowired
> private Validator jsr303validator;
>
> @Override
> public boolean supports(Class<?> clazz) {
> return EObject.class.isAssignableFrom(clazz);
> }
>
> @Override
> public void validate(Object target, Errors errors) {
> if (jsr303validator!=null) {
> jsr303validator.validate(target, errors);
> }
> EObject eObject = (EObject) target;
> Map<Object, Object> context = new HashMap<Object, Object>();
> context.put(SubstitutionLabelProvider.class,
> new SubstitutionLabelProvider() {
> @Override
> public String getObjectLabel(EObject eObject) {
> return eObject.eClass().getName();
> }
>
> .......
> });
> BasicDiagnostic diagnostic =
> Diagnostician.INSTANCE.createDefaultDiagnostic(eObject);
> Diagnostician.INSTANCE.validate(eObject, diagnostic, context);
>
> if (diagnostic.getSeverity() != Diagnostic.OK) {
> for (Diagnostic child : diagnostic.getChildren()) {
> String errorCode =
> MessageFormat.format("{0}.{1}",eObject.eClass().getEPackage().getName(),
> eObject.eClass().getName());
> errors.reject(errorCode, new Object[] {eObject},
> child.getMessage());
> }
> }
> }
>
>
>
> Finally I it is soo simple to use this composition of JSR303 and EMF
> validator in your Spring MVC application - you just use the @Valid
> annotation on the controller's mapping, like I do here:
>
>
> @RequestMapping(method=RequestMethod.POST)
> public String create(@Valid Subscriber subscriber, BindingResult
> result) {
> if (result.hasErrors()) {
> return "subscriber/create";
> }
> dao.persist(subscriber);
> return "redirect:subscriber/" + subscriber.getId();
> }
>
>
>
> Hope someone will find this useful.
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
|
Powered by
FUDForum. Page generated in 0.03202 seconds