Complex bean validation - bean-validation

How can I validate the below class using validator (JSR303) API? This should be done using Hibernate Validator API.
Suppose TesterBatters class itself has some validation. How can I validate those?
public class Example {
private String jseId;
private String jseType;
private String jseName;
private Double jsePpu;
private TesterBatters jseBatters;
private List<TesterToppin> jseTopping;
public String getTesterId() {
return jseId;
}
}

You basically have to add constraint annotations such as #NotNull, #Size etc. to the elements of your model (i.e. the properties and/or classes) and perform a validation of these constraints at a suitable point of time (e.g. when persisting objects or processing data entered by the user into a GUI) using the javax.validation.Validator API.
To recursively apply a validation to referenced objects, use the #Valid annotation.
I recommend to have a look into the Hibernate Validator reference guide which explains in detail how to work with Bean Validation.

Related

Get all annotated classes and call each method to get a return value

I am creating a small validation application using Spring MVC. I am very new to Spring MVC and would like to ensure that what I want is possible.
I have simplified my problem.
I have setup a controller that will be called when a URL is executed. localhost/validate/{SOME TEXT}
The {SOME TEXT} value with be sent to all my validation classes I created.
I currently have 4 classes which does the validation and returns another Object data about what happened during the validation
The 4 validation classes are:
CreditCardValidator
AddressValidator
ZipcodeValidator
AccountNumberValidator
I have a main controller bean that when called I want the string to be passed to each class and the object returned from each to be stored and then finally all results are sent back in a response.
Normally, I would do this without Spring by creating an interface that each validation class implements. Then iteration through the list of classes and execute a method.
The problem doing it that way is that whenever I need to add a new validation class I'll need to register it so the request can use it. This involved modifying existing classes.
Since I am using Spring quick heavily in this application I am wondering if this is possible to do via Spring and annotated classes.
I was thinking of creating a custom annotation that each validation class has and then using spring component-scan to get the classes. This would allow me to create new validations without modifying existing code.
Below is the what I am trying to do.
#Controller
public class StringValidationController {
#RequestMapping(value = "/validate/{text:.+}", method = RequestMethod.GET)
public ModelAndView index(#PathVariable("text") String text) {
ModelAndView model = new ModelAndView();
model.setViewName("index");
model.addObject("result", getListOfValidatedData());
return model;
}
public List getListOfValidatedData(){
//Scan for IValidator annotation
//call each concrete class and pass in text
// get object with has validation information in it
}
}

Spring Autowiring by variable name

Below is my controller. My program generates an output, based on a form input. Across the project, there are multiple input forms, that generate the output object. So, the essential flow is the same. So I want a single multi-action controller that does all of that.
Challenges:
1. The service classes change. Although all services implement the same interface, and controller calls the same interface method.
2. The input objects change. Although the input objects do not have any methods other than setters, and getters. So I let them all implement an empty interface.
Questions:
How do I change the qualifier, based on the path. Can I use path variables?
Suppose the path has this value -> singleton. Then my corresponding bean names would be singletonService and singletonInput. I want to make a constant class that has stores this mapping information. So, can I call that from inside the qualifier, using some Spring Expression Language? Example, instead of Qualifier(variablePathName) -> Qualifier(getQualifierName['variablePathName']) Something like that?
Please also clarify the theory behind this. From what I understand, beans are created, autowired before the Request are mapped... Does this mean that what I'm trying to achieve here is simply not possible. In that case, would you suggest making Controller-service pairs for handling each request, with basically the same code? But I feel there must be some way to achieve what I'm trying...
Code:
#Cotroller
#RequestMapping(value="/generate/{path}")
public class TestController {
#Autowired
#Qualifier(......)
private IService service;
#Autowired
#Qualifier(......)
IUserInput userInput;
#RequestMapping(method = RequestMethod.POST)
//Some handler method
}
You're right in that the autowiring is all done once up front (point 3). You wouldn't be able to achieve what you want using fields annotated #Autowired and #Qualifier - as these fields would always reference the same bean instance.
You may be better to ask Spring for the particular service bean by name - based on the path variable. You could do it within a single controller instance. For example:
#Cotroller
#RequestMapping(value="/generate/{path}")
public class TestController {
#Autowired
private ApplicationContext applicationContext;
#RequestMapping(method = RequestMethod.POST)
public String someHandlerMethod(#PathVariable String path) {
IService service = (IService) applicationContext.getBean(path + "Service");
IUserInput userInput = (IUserInput) applicationContext.getBean(path + "UserInput");
// Logic using path specific IService and IUserInput
}
}

Jsr303 specify group on association validation

I am facing an issue when validating object which has more than one relationship to bean of particular type but each of relationship must be validated in a different manner.
Composite class:
public class Composite{
#Valid
private Person insurer;
#Valid
private Person insured;
...(other properties)
private String foo;
}
Person class:
public class Person{
#NotNull(groups={Insurer.class,Insured.class})
private String name;
#NotNull(groups={Insurer.class,Insured.class})
private String surname;
...
#NotNull(groups={Insurer.class})
private String ssn;
}
So we have a single type Person which can represent insurer and insured. The problem is that when validating Composite i want to have insurer property to be validated with Insurer group and insured with Insured. Is there anyway it can be accomplished or i need to wait for https://hibernate.onjira.com/browse/BVAL-208 resolving...
To solve your issue in a standardized way you indeed have to wait for Bean Validation 1.1 which will address BVAL-208 (group translations).
In case your Person class also has a flag or some other criteria you could use to determine whether this person is an insurer or insured you could also use a custom class level constraints. The downside is that you are loosing some of the expressiveness of annotations, since you would have to do all validation yourself in the custom constraint validator implementation.
The other alternative (again you need a way to distinguish between insurer and insured) is to use the Hibernate Validator specific GroupSequenceProvider. This way you can keep your current configuration and you just would return the right group depending on the type of Person.

Grails data binding

I need to bind request parameters to an instance of the following Java class (getters and setters omitted):
public class ShippingHouse {
private String name;
private String description;
private List<ShippingRule> shippingRules = new ArrayList<ShippingRule>();
}
public class ShippingRule {
private ShippingHouse shippingHouse;
private String name
}
Notice that there is a 1:N relationship between ShippingHouse and ShippingRule, but each ShippingRule also has a reference to the ShippingHouse thaat owns it.
If these were Grails command/domain classes, I would bind them with request parameters
name=foo&description=bar&shippingRules[0].name=sr0&shippingRules[1].name=sr1
But it doesn't seem like this will set the reference to the owning ShippingHouse within each ShippingRule. Is there a way I can bind this automatically, or must I write the code myself?
Don,
You will need to write code to do it yourself using BindUsing or some other approach. The binder doesn't (and shouldn't) assume anything about back references from a parent to a child. If these were GORM entities and the relationship was explicit, that is different, but in your case the binder should not assume that shippingHouse property in the ShippingRule class has anything to do with the shippingRules property in the ShippingHouse class.
Also note that lucke84 said that your "private" is implicit. Make sure you understand what that means if you are going to remove them. If you remove them the compiler is going to generate public getter and setter methods for those properties, which may or may not be what you want.
If you want to implement a 1:N relationship between the two classes, you should use the right grails approach. Something like this:
class ShippingHouse {
String name
String description
static hasMany = [shippingRules: ShippingRule]
}
class ShippingRule {
String name
static belongsTo = [shippingHouse: ShippingHouse]
}
Please note that semicolons are useless and the "private" declaration on class fields is implicit.

What Spring MVC controller to use for form with dynamic fields

I have a form where I have two fields that I can add as much as I can. Think of it as like the upload file in gmail where I can add 1,2,3... files to upload only that I have two fields.
I am not so sure how this will check out using a SimpleFormController in Spring. Will the Spring Controller bind the them automatically?
My command class looks like this:
public class Course {
private long ID;
private String Owner;
private String Title;
private String Learning Objective;
//I am not so sure how this will be bound
private List<LearningActivity> learningActivities;
//accessor methods
}
public class LearningActivity {
private String Description;
private String link;
//accessor methods
}
I would suggest you to use Annotation-based Spring controllers as SimpleFormController is deprecated as of spring 3.0
If you are using annotations based
controller then their is no need to
extend any class or implement any
interface. The only thing you need to
do to make your simple java class to
become a Spring controller is to add
the #Controller annotation to it.
Example here
Also for handling dynamic fields in the form, it is better that you use Spring Form Tags
Example here
Edit: check 5.4.2.1. Registering additional custom PropertyEditors in spring docs, it has an example of what u want

Resources