I have an Java Server Faces web application and I am unsure how to handle the validation.
In my opinion the validation should be done in the bussiness logic tier. The business logic layer is used inside the web presentation (jsf) and REST-API.
At the moment i am doing also the validation inside the jsf layer with the provided validators. I think that is in the most cases only duplication of code. Is there any way to avoid this code duplication? Is java server faces able to use the validation exceptions that i am throwing inside the business logic layer?
Bean Validation has been invented for exactly this case.
You annotate your entities with constraints, and these constraints will be honoured by both your business logic (via EJB, CDI and/or JPA) as well as by JSF.
For the small amount of validations that you can't express via Bean Validation but are truly business associated; yes, throw an exception, catch it in your backing bean and set a corresponding Faces message (hint: use OmniFaces' Messages to make this easier). Equally, for the small amount of validations that you can't express with Bean Validation and which are strongly view oriented; use JSF native validators.
Related
Can we use JSON Schema Validation in the place of Java Bean Validation JSR303 for Spring Boot Rest APIs for Enterprise Applications? Which one is more efficient to validate request Payload to Spring Boot Rest APIs?
(i.e. performance wise, cross-validation wise and RegEx pattern based validation)
It is a good question and there are no definitive answers for it as, perhaps, it is dependent on the application domain and remains subjective to that. At the base level (which usually covers 90%) of all use cases of validating user input to the REST service, both have the equivalent facility to validate data adequately. Both support constraints which can be used to achieve the same result.
However, on one front Bean Validation stands out is its ability to define custom validators, which can be used to validate very specific domain/application dependent constraints. For example, if there is case where a class which has 3 attributes (say, A,B and C) and a constraint is required that is either A occurs or B & C occurs but not both, then it is not really possible to put a constraint in JSON schema directly, it has to be handled through design of the schema (similarly in XML, actually it is more complicated with XML).
On the other hand in Bean Validation a custom validator can be written to handle this situation quite easily.
However, these kind of cases are few and far between.
Another point to consider is the integration of the Bean Validation in the underlying framework e.g. Spring, Jersey, RESTEasy etc., JSON schema validation is not yet integrated in the frameworks.
Therefore, given the support for the tech, it is perhaps better to stick with Bean Validation 2.0 and leverage the underlying frameworks capability to validation (this is, however, purely my view).
From an application development prospect, Java bean validator is sufficient for the business needs. From a system integration point, JSON schema externalizes the business rules and provides a platform independent interface control. So if your system involves many subsystems, JSON schema gives a better way to verify message payload.
I prefer OpenAPI Specification, which can be regarded roughly as a JSON Schema dialect, to bean validation 2.0 (JSR380).
OpenAPI is the de-facto (correct me) standard to describe RESTful API today. There are tools for validation accroding to OpenAPI spec is available, an incomplete collection can be found at here. And of course it works well with Java/Spring.
OpenAPI validates JSON string rather than a POJO, thus it can handle the following case naturally while bean validation in Java cannot: say i want to validate the object in the request body of a PATCH request, and the object must have a property named A, while the value of A is can be null;
And there are more than validation you can do with an OpenAPI spec in your hand. Because an OpenAPI schema does not only define what the data model of RESTful API looks like, it also describes other aspects (endponts, parameters and status code etc.) of the API in the same file. Out there are a bunch of code generators to auto-generate server-side or client-side code to serve requests or retrive response in whatever language.
I have been working on a system that does user input validation only on the JSF Managed Beans. Theoretically, on the college bench, we are told to always replicate the validation on the business layer (or when it is not possible, on the persistence layer: through Bean Validation API or Hibernate Listeners).
However, after some research, I concluded that there is no security breach on that because JSF does not allow direct access to nothing "bellow" it. But I really want to be proven wrong.
It may not be a security breach when you are only using JSF. In general I think it's best to have your validation and authorization as close to your data storage as possible. If you for example would decide to add a REST service to your application, your validation and authorization is already taken care of.
If you are using javax.validation, there is no need to replicate the validation in JSF when you are using a component library like PrimeFaces. In PrimeFaces you can simply use bean validation based on your javax.validation annotations.
Spring MVC offers form validation through both annotations on the forms (for example #NotNull) to do a simple check of the value of a field, and custom Validators, which help you do cross-field validations (verifying two password fields contain the same value, etc).
I am looking for the recommended way to do validations that go a bit further, however. For example verify if a username is not used already, which requires a call to the database. I assume I can simply inject my PersonRepository into the custom validator (which is an #Component) after all, but I doubt it'll be transactionally safe..or very clean.
What is the recommended way to do this, that requires the least amount of duplicated code? Or should I simply write my own validation layer, that throws some ValidationException with a list of validationmessages, which I have to map to the bindingresult?
To just clearify: Spring MVC don't offers form validation by itself. It integrates with Java Bean validation vendors (like Hibernate Validator).
You're right: If you configure LocalValidatorFactoryBean as a bean in your application context, you benefit from dependency management in your custom validators. In my opinion there is no need to implement a custom validation layer within your setup, since you already have a powerful and generic abstraction of validation which even conforms to Java standards.
If you worry about whether calling your repository in validator is transaction safe or not see http://docs.spring.io/spring-data/jpa/docs/1.8.2.RELEASE/reference/html/#transactions for details. CRUD operations are transactional by default. If you need a more sophisticated validation logic with needs a transaction context, you could either make your isValid(...) method transactional by annotating it, or you could autowire a business service with likely is transactional by itself. This perfectly integrate with the concepts of Spring.
Use the same business transaction
If you need to handle validation and business logic (check whether a user name is already used and insert a new if not) in the same transaction you could think about restricting those validations in Controller layer to the basic ones (#NotNull for example). This will ensure, that only syntactic correct requests make their way to your service layer.
In the service you will use an autowired validator and trigger the entire validation constraints manually. If you have a combination Hibernate as JPA vendor and Hibernate as Validation vendor you could even make use of the integration of both (pre persit and pre update events) which will cause the validation to occur automatically before the changes are written to the database.
However you decide, you will likely use validation groups to split the constraints into two groups 'syntactic' and 'semantic' for example. If you call the validator manually you can pass the groups you want to take into account. If you use integrated validation with Hibernate you can control the groups for the different events by specifying the following properties:
javax.persistence.validation.group.pre-persist
javax.persistence.validation.group.pre-update
If you decide for this way you will simply call your transactional business service method from your controller. Business logic and validation will participate in the same transaction this way.
I am using Spring and JSF2 a lot and was wondering what the best way to integrate them is? Now i understand there are basically two ways to do this, but i have some problems with both:
a) Use normal #ManagedBean, and inject Spring-Services into that beans using #ManagedProperty: The problem is that i can't use Spring-AOP inside a #ManagedBean obviously, because it is not Spring-managed. I usually use an arround-aspect on every method annotated with my custom annotation #DatabaseOperation. Another example would be #Secured from Spring-Security and so on. I use a lot of AOP in my project and not beeing able to use them on "the top level" is really limiting for me.
b) Use SpringBeanFacesELResolver to make everything managed by Spring. On the pro side is that AOP works like a charm, but the cons are big too:
No ViewScope. I am not sure if i can trust custom view scope implementations like this https://github.com/michail-nikolaev/primefaces-spring-scopes on productive systems?
Serialization is not possible. It's already pretty complicated, but once i use AOP i can't get it to work because org.springframework.aop.aspectj.AspectJPointcutAdvisor is not Serializable
So my question is: How do you overcome this issues? How do YOU integrate JSF2 and Spring3.x? I have been using possibility b) mostly, but on my next project i need session replication..
Any further suggestions?
The main integration pain point of the two frameworks is that JSF is usually used in a stateful way. to make the integration the most seamless, you would have to let Spring handle the statefulness and page navigations aspects himself instead of JSF, as well as bean creation and scoping.
The second important integration point is at the level of the view expression language. We want to be able to access spring beans while building the view, which means the managed bean layer is no longer needed.
The best integration available for the two frameworks is provided by introducing Spring webflow, see here for further details. With SWF, JSF no longer manages beans itself, this is done by Spring. JSF does not manage page navigation anymore, this handled in the SWF flow definition.
Also the statefulness is handled by SWF. The flow definition XML file replaces large parts of the faces-config.xml for view navigation, transition actions, bean definition, etc.
Using the SWF JSF integration means that your faces-config.xml is mostly empty. Expression language accessing directly spring beans can be used while building the view, and a view scope is available.
If you want to keep a page isolated from the rest of the application, youcan create a flow with a single view state and self-transitions. An advantage of SWF is that it prevents duplicate form submissions via a POST-REDIRECT-GET mechanism that works transparently out of the box.
I am planning to use Spring 3 validations in my Web Application. I was considering that since I already have the properties of my JPA entities annotated with some standard validations like nullable="false" or length="50". Is there any way I could reuse JPA validations in Spring 3 Backing forms?
I feel a better idea would be to recode the validations on the Spring form as we can have more helpful error messages. What do you think -
Is it possible in a clean way to reuse JPA validations in Spring forms?
What is a better design - reimplement the validations or reuse the basic ones and code more specific validations separately?
In my experience, as soon as you write a custom Validator you're responsible for validating all fields regarding Spring's WebDataBinder. Validation constraint annotations still throw exceptions though if violated.