a question about the design Validation using JSF framework - validation

In software design sort of way, what is best: checking unique input (e.g username) in the DB using a JSF Validator, or using the Controller (managed-bean).
Apparently, in JSF framework, I can't use #EJB in the Validator, so in case I use the Validator for the checks, then I would have to connect to the DB in another way (jdbc connection or something).
In case I check this one in the Controller, I would have to put some logic that is not necessary a part of the process (for example: createUser method).
So, what is the best way according to the JSF framework?

Apparently, in JSF framework, I can't use #EJB in the Validator, so in case I use the Validator for the checks, then I would have to connect to the DB in another way (jdbc connection or something).
That's right. A common workaround for this is to declare and use the validator as a #ManagedBean.
E.g.
#ManagedBean
#RequestScoped // Can be #ApplicationScoped if it does not hold any state.
public class UsernameValidator implements Validator {
#EJB
private UserService userService;
// ...
}
with
<h:inputText validator="#{usernameValidator.validate}" />
or
<h:inputText>
<f:validator binding="#{usernameValidator}" />
</h:inputText>

Related

Will the #Validated annotation in the DAO Interface help at all?

I have seen a lot of #Validated annotations in the DAOs interface that I didn't write. For example:
#Validated
public interface CompanyDAO extends BaseDAO<Company> {
public List<Company> list();
What behaviour should I expect from this:
Validating all the objects passed to the DAO before saving them into the database?
Validating all the objects that the DAO retrieves from the database?
Both of them?
Nothing at all. This annotation should not be placed in DAO interfaces.
Just a few pointers which you might not be aware of:
8.8 Spring Validation of 8. Validation, Data Binding, and Type Conversion in the manual specifies that
In order to be eligible for Spring-driven method validation, all target classes need to be annotated with Spring’s #Validated annotation, optionally declaring the validation groups to use. Check out the MethodValidationPostProcessor javadocs for setup details with Hibernate Validator and Bean Validation 1.1 providers.
MethodValidationPostProcessor says
Applicable methods have JSR-303 constraint annotations on their parameters and/or on their return value (in the latter case specified at the method level, typically as inline annotation), e.g.:
public #NotNull Object myValidMethod(#NotNull String arg1, #Max(10) int arg2)
Target classes with such annotated methods need to be annotated with Spring's Validated annotation at the type level, for their methods to be searched for inline constraint annotations. Validation groups can be specified through #Validated as well. By default, JSR-303 will validate against its default group only.
So, maybe the answer to your question
What behaviour should I expect
is: Whatever constraints are given in the code.

Using same validation logic for Rest, JSF, biz layer

I'm wondering if there is a way and if there is, what is the correct one, to use same validation logic (one implementation) for JSF, in EJB beans and web services - rest (RestEasy).
Currently Hibernate entities are used across all layers, because I feel my project is too small to complicate it with additional DTOs on the presentation layer, but the rest service will use DTOs.
How do I approach this problem?
Thanks!
Java EE offers JSR303 Bean Validation API for exactly this purpose. You perhaps already have seen them around, #NotNull and friends. This is by default automatically recognized and supported by both JSF and JPA. JAX-RS usually don't have a "view" which should take/validate input, so it's not of relevance here.
So, instead of e.g. JSF
<h:inputText value="#{bean.entity.property}" required="true" />
with solely
private String property;
you can just use
<h:inputText value="#{bean.entity.property}" />
with
#NotNull
private String property;
This can then also be used by JPA in case you're putting data via JAX-RS.
Only thing you need to take into account in JSF side is that it by default sets empty fields as empty string instead of null. You use the following web.xml context parameter to tell JSF to interpret empty string submitted values as null:
<context-param>
<param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
<param-value>true</param-value>
</context-param>
See also:
Java EE 7 tutorial - using Bean Validation constraints
Empty input value does not triggger #NotNull but it triggers #NotBlank

Spring DTO validation in Service or Controller?

I'm building a straight forward AJAX / JSON web service with Spring. The common data flow is:
some DTO from browser
v
Spring #Controller method
v
Spring #Service method
I'm looking for the most easy way to handle data validation.
I know the #Valid annotation which works pretty well inside #Controller methods.
Why does #Valid not work within #Service methods?
I mean: A service method can be used by any other service and controller. So wouldn't it make much more sense to validate at #Service level?
Let's take this simple example:
MyDTO.java:
public class MyDTO {
#NotNull
public String required
#Min(18)
public int age;
}
MyServiceImpl.java:
public MyDomainObject foo(MyDTO myDTO) {
// persist myDTO
// and return created domain object
}
MyController.java:
#Autowired
MyService myService;
#Autowired // some simple bean mapper like Dozer or Orika
Mapper mapper; // for converting domain objects to DTO
#RequestMapping(...)
public MyDomainObjectDTO doSomething(#RequestBody MyDTO myDTO) {
mapper.map(myService.foo(myDTO), MyDomainObjectDTO.class);
}
Is it common practice that the service method receives the DTO?
If yes: What's the best practice to validate that DTO inside the service method?
If no: Should maybe the controller manipulate the Domain object and just let the service save that object? (this seems pretty useless to me)
In my opinion the service should be responsible for only data consistency.
How do you solve this?
My answer? Both.
The service must check its own contract for validity.
The controller is part of the UI. It should validate and bind for a better user experience, but the service should not rely on it.
The service cannot know how it's being called. What if you wrap it as a REST service?
The service also knows about business logic violations in a way that no UI can. It needs to validate to make sure that the use case is fulfilled appropriately.
Double bag it; do both.
See my other answer: Check preconditions in Controller or Service layer
If you really want to do validation like error handling in your Service layer similar to Spring MVC you can use javax.validation and AspectJ (to advice the methods to validate) which is what I do because I like making reflection do the work and declarative programming (annotations).
Spring MVC doesn't need to do AspectJ/AOP to do the error handling because the methods are being called through reflection (url routing/dispatching).
Finally for you MVC code you should know that #Valid is sort of unofficially deprecated. Instead consider #Validated which will leverage more of the javax.validation features.

Spring config and runtime separation

When using Spring it is rather cumbersome to incorporate runtime data in bean construction. While there are techniques to circumvent this separation, I have a feeling that it was put in place for a reason. My question is whether this is a known paradigm, and if there is any litterature discussing it. Personally I find that it has both advantages and drawbacks, depending on the dynamicity of the app.
You have at least five well known methods to pass runtime data to beans configuration:
Use ApplicationContextInitializer to add PropertySources to the Enviroment.
Use SPEL to inject dependencies.
Use FactoryBeans.
Use the factory-bean and factory-method attributes.
If you write the class that need the runtime data, you only need to inject the
collaborator that provide it.
For example
<bean id="requestAttributeReader" class="example.RequestAttributeReader" />
<bean id="requestInjectedBean" class="example.RequestInjectedBean" scope="request">
<property name="a" value="#{requestAttributeReader.a}" />
</bean>
Class RequestAttributeReader {
public String getA() {
return RequestContextHolder.getAttributes().getAttribute("a");
}
}
EDIT
The bean description files of an IoC container lets you to configure implementors on application beans. This is normally a static definition of the implementation classes that you want to use for a concrete configuration, so xml it's good for it.
If you need to choose an implementor based on runtime then you need to write code to choose them and then inform the container.
for example, using PropertySources and PropertyPlaceholderConfigurer:
String service = "example.NormalService";
if (BOSS_USERNAME.equals(System.getProperty("user.name")))
service = "example.BossService";
ctx.getEnvironment().getPropertySources().addFirst(new PropertiesPropertySource("service", service));
<bean id="service" class="${service}" />
The same could be done with a ServiceFactoryBean, a external ServiceFactory, SPEL and so on...
Maybe, you are interested on replacing implementations at runtime, ie changing the Service implementation in all beans that depends on when the container is already refreshed. (without destroy and refresh).
As far as I know, the framework don't provides a clear way to do it.
Sounds like you should look at spring binding, eg:
public String create(#Valid Market market, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest) {
So this will take request params that match the fields in the Market object and set them in that object. It will also validated the params/object since there is the #Valid annotation.
This binding can be customised with PropertyEditors or Converters.
If the market object is annotated #Configurable, it can use #Autowired and #Value annotations to configure the bean when spring creates it.

Display datatables values from databse using spring injection in a ManagedBean

Got this design issue with JSF + Spring :-
I got a datatable on a page to be loaded showing user details, which is to be fetched form Database.
So my jsf page has :
<p:dataTable id="userTable" var="user" value="#{userBean.users}" rowKey="#{user.userID}"
selection="#{userBean.selectedUser}" paginator="true" rows="10" >
Managed bean has:
private List<UserDetails> users; // getters and setters
Now my managed bean needs a spring injection of the helper class to fetch the users from DB.
#ManagedProperty(value="#{userBO}")
private UserBO userBO;
The problem is , spring injection happens when the object is completely instantiated. So I cannot place my userBO.getUsersFromDataBase() in the constructor and assign it to my users
I just can't figure out how to fetch users from DB,using spring injection in my managedBean. Spring needs the instantiation of the ManagedBean to be complete so that it can inject the helper class, but the jsf page requests the database values much before the ManagedBean is completely instantiated. Kinda stuck :/
I am not familiar with spring, however in standard JSF you can use the #PostConstruct annotation on a method that will be invoked after construction and after dependency injection, e.g.:
#PostConstruct
public void init() {
userBO.getUsersFromDataBase()
}

Resources