JSF Generic Validator - model-view-controller

I want to write a generic validator for checking name of a entity is exist or not.Currently i am doing this ,writing a new validator class for every Entity object,How can i specify Class type of entity bean dynamicly and write a generic validator for entity objects.
public class LemfValidator implements Validator {
public void validate(FacesContext context, UIComponent arg1,
Object name) throws ValidatorException {

This is balusc post .It solve my problem.
http://balusc.blogspot.com/2007/12/validator-for-multiple-fields.html

Related

How to register validator for Spring Data Rest?

There are two ways to register a Validator instance in Spring Data REST: wire it by bean name or register the validator manually. For the
majority of cases, the simple bean name prefix style is sufficient.
In order to tell Spring Data REST you want a particular Validator
assigned to a particular event, prefix the bean name with the event in
question. For example, to validate instances of the Person class
before new ones are saved into the repository, you would declare an
instance of a Validator in your ApplicationContext with a bean
name of beforeCreatePersonValidator. Since the beforeCreate prefix
matches a known Spring Data REST event, that validator is wired to the
correct event.
I tried creating this bean but it doesn't register
#Component("beforeCreateOrderValidator")
public class BeforeCreateOrderValidator extends BaseValidator {
#Override
public boolean supports(Class<?> clazz) {
return Order.class.equals(clazz);
}
#Override
public void validate(Object obj, Errors errors) {
}
}
But if I do manual registration it works
#Override
public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener v) {
v.addValidator("beforeCreate", new BeforeCreateOrderValidator());
}

How can #Validated work on common method?

In Springboot project, when I try to add #Validated on controller method, it worked.But now I want to add it on a common method, then failed.
Try to add #Validated on controller method, it worked
public class TaskValidator {
private static final Logger logger = LogManager.getLogger("TaskValidatorLogger");
public void validateTest(#Validated Test test) {
logger.info("Validate: {}", test.getName());
}
public static void main(String[] args) {
new TaskValidator().validateTest(new Test());
}
}
#Data
public class Test {
#NotNull(message = "name can not be null")
private String name;
}
It should throw an MethodArgumentNotValidException but not.
Spring MVC has the ability to automatically validate #Controller
inputs. In previous versions it was up to the developer to manually
invoke validation logic.
In the controller methods, springboot automatically binds any validators to the model and invoke it when the data is bound to the object.
But in your case , you are trying to validate an object in which case , springboot might not be automatically binding your validator to your model and call the validator.So, in that case, you will need to manually bind the object to the validator.
or you can manually invoke the validator on a bean like :
#AutoWired
Validator validator;
...
validator.validate(book);

Spring Security: get controller class in Preauthorize annotation

Many of the controllers I use in a Spring application extend a common abstract class. The methods are thus declared in the abstract class.
I would like to apply a 'PreAuthorize' condition in the abstract method, but I need to get the name of the actual controller class being invoked to be passed to the EL evaluator.
Is there a way to do so?
In abstract class implement BeanNameAware interface.
public abstract class MyController implements BeanNameAware{
String beanName;
#Override
public void setBeanName(final String beanName) {
this.beanName = beanName;
}
#Override
public String getBeanName() {
return beanName;
}
}
You will get a hold of actual bean name instead regular proxy. If you need further customization implement BeanFactoryAware. You can than use that getBeanName method in SpEl of your preauthorize

spring dependency interface injection with two implemented classes

consider a scenario of interface injection in spring, I have an interface which was implemented by two class. If we inject the Interface in another class using #Autowired. Now if we call a method in that interface then which class implemented method will be called? consider that we are not using #Qualifier annotation.
enter code here
public interface EmployeeDAOI{
void save();
}
public class Emp1 implements EmployeeDAOI{
public void save(){
//some logic
}
}
public class Emp2 implements EmployeeDAOI{
public void save(){
//some logic
}
}
now we inject EmployeeDAOI to some class
public class IterfaceEx{
#Autowired
private EmployeeDAOI edaoi;
public void setEmployeeDAOI(EmployeeDAOI edaoi){
this.edaoi=edaoi;
}
edaoi.save(); // My question is here which class method will be called ?
}
None.
You get an exception:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [EmployeeDAOI] is defined: expected single matching bean but found 2: [emp1 , emp2]
Spring expects exactly one instance, unless the injection is done for a Collection of those instances or you use a way of differentiating (#Qualifier).

Using both JSR-303 and Traditional Bean Validation?

Is it possible to use both JSR-303 bean validation and traditional validation (a single validator class for the type) in Spring? If so, what configuration is required to set this up?
I have tried the instructions on the reference.
#InitBinder
protected void initBinder(WebDataBinder binder) {
binder.setValidator(new DualEntryValidator());
}
#RequestMapping(value="/dualEntry.htm", method = RequestMethod.POST)
public ModelAndView handlePost(#Valid DualEntryForm form, BindingResult result) {
ModelAndView modelAndView = new ModelAndView("dualEntry", getCommonModel());
if (!result.hasErrors()){
//do logic
return modelAndView;
}else {
modelAndView.addObject("dualEntryForm", form);
return modelAndView;
}
}
I can get this to use my custom Validator or the JSR-303 validation, but not both. If I have the initBinder present as in the example it uses the custom Validator. If I remove it the JSR-303 bean validation is used. How can I use both?
I've done that following the instructions here:
http://blog.jteam.nl/2009/08/04/bean-validation-integrating-jsr-303-with-spring/
See the "Enjoy both worlds" section. Shortly, you explicitly run a JSR303 validation from a Spring validator, "joining" the results of JSR303 validations based on annotations and your custom validation logic.
I realise this is quite old, but I got this to work with minimal disturbance to my code
Change binder.setValidator(new DualEntryValidator());
to
#InitBinder
protected void initBinder(WebDataBinder binder) {
binder.addValidators(new DualEntryValidator());
}
With setValidator() you're replacing the JSR-303 validator with your one. With addValidator(), the JSR-303 validator is called and so is yours.
You need to make sure that your validator does not overlap with your JSR-303 #NotNull, #Min, #Max, etc. annotations otherwise you'll get duplicate error messages added.
Spring provides three handle for bean validation.
1.abstract class AbstractPropertyValidationAnnotationHandler
2.abstract class AbstractMethodValidationAnnotationHandler
3.abstract class ClassValidationAnnotationHandler
In this example i am implementing custom annotation CustomAnnotationHandle
#Target({ElementType.METHOD, ElementType.TYPE})
#Retention(RetentionPolicy.RUNTIME)
#Documented
Class CustomAnnotationHandle extends Annotation{
public abstract String value();
}
To implement custom annotation for property validation we need to extend AbstractPropertyValidationAnnotationHandler Class.
AbstractPropertyValidationAnnotationHandler provides createValidationRule abstract method
protected abstract AbstractValidationRule createValidationRule(Annotation annotation, Class class1, String s);
So,the extended class must provide implementation of
protected abstract AbstractValidationRule createValidationRule(Annotation annotation, Class class1, String s)
public class CustomPropertyAnnotationHandler extends AbstractPropertyValidationAnnotationHandler
{
public CustomPropertyAnnotationHandler()
{
super(new Class[] {
XXX.XXX.PackageLevle.CustomAnnotationHandle // as it takes array of custom annotation ,so we can pass more than one
// overwriting abstract method
protected AbstractValidationRule createValidationRule(Annotation annotation, Class class1, String s){
CustomAnnotationHandle value = (CustomAnnotationHandle)annotation;
return TestValidationRule(value.getValue());
// as you can see it return AbstractValidationRule.So, we need a class to give our bean specific validation rule.In our case it is
//TestValidationRule
}
}
}
public class TestValidationRule extends AbstractValidationRule
{
public TestValidationRule (String valuetest)
{
super();
this.valuetest = valuetest;
}
Private String valuetest;
}
Spring provides AnnotationBeanValidationConfigurationLoader Class.This class is used for spring own annotation for bean validation.
DefaultValidationAnnotationHandlerRegistry class is used as defaultHandlerRegistry.But if we need to provide our own annotaion then we
need to extend AnnotationBeanValidationConfigurationLoader and set our specific handleregistry via method
setHandlerRegistry(new CustomPropertyAnnotationHandler());
Class DefaultValidationAnnotationHandlerRegistry is used to register spring own annotation for bean validation.It register bean by
calling registerPropertyHandler method of SimpleValidationAnnotationHandlerRegistry class.So for our custom annotation we need to
register CustomPropertyAnnotationHandler by calling registerPropertyHandler method of SimpleValidationAnnotationHandlerRegistry class
public class OurBeanSpecificValidationLoader extends AnnotationBeanValidationConfigurationLoader
{
public OurBeanSpecificValidationLoader ()
{
super();
setHandlerRegistry(new OurSpecificAnnotationHandleRegistery ());
}
}
public class OurSpecificAnnotationHandleRegistery extends DefaultValidationAnnotationHandlerRegistry
{
public OurSpecificAnnotationHandleRegistery ()
{
registerPropertyHandler(new CustomPropertyAnnotationHandler() );
}
}
so you have your custom annotation for bean valiation.E.g
#CustomAnnotationHandle(value = "test")
private Object test;

Resources