Flex/Spring/Hibernate validation - spring Validator and ExceptionTranslator - spring

I'm beginner in mentioned technologies and forgive me if I ask some dumb questions.
I have design problem with validation code in my app. Very often i break the DRY principle. Besides, validation confuses me somehow. I always questioning myself where to put some validation stuff, checked vs unchecked, what to propagate, what to validate etc. Still, there are some topics about mentioned stuffs, so i will concentrate on my specific problem with F/S/H technologies.
For example, my DAO save method have following validation:
public void save(Person p){
if(p==null) throw IllegalArgumentException("Person object is required...");
//...
}
Exactly the same validation i also have in delete, update and read methods in DAO layer.
I was looking for some solution with com.springframework.validation.Validator interface, but I bump in to problem with propagation of error codes to Flex client.
Maybe, i could do something like this...
public void save(Person p){
BeanPropertyBindingResult err = new BeanPropertyBindingResult(p,"Errors");
//myValidator will be injected
myValidator.validate(p,err);
//...
throw MyException("Message",err);
//...
}
I don't know if this is good approach. What validation approach to use to minimize repetition of such validation code. If someone can to give me some direction, hint, link, I'll appreciate it.

Maybe you should try some Design by Contract annotation driven solution like Contract4j?

Related

How to use Spring AOP's Aspect to do very complex audit logging?

I'm building a Spring web application. Using Spring AOP's aspect to do audit logging.
I've got business class with methods like the following and i want to audit log in certain cases
during method execution
after method returns
#Aspect
public class MyBusinessClass {...
public void registerUser() {
// do some business logic here...
userId = // userService.saveUser(...).getId(); // etc...
if(successful) {
// then send Email notification
audit.log(userId, "success sending email notification"... some other params);
else {
audit.log(userId, "fail to send email notification"...);
}
//do some more logic before returning method
audit.log(userId,"successfully registered user...." ...);
..// method returns
}
I've already got Aspects defined in a separate class.
I'm having problems because all the common simple examples i've seen on here and on other articles seemed to be very simple. For example, they work easily because the most complicated i've seen only go as far as extracting method params into the aspect's advice..
But my problem here is that i wan't to somehow not just extract local variables into the Aspect's advice but do the audit logging more than once and also based on certain conditions.
Don't get me wrong, we've already got Log4j logging to log to file in the same places but we also require to do these audit logging to DB too.
I just want to know what's the solution to achieve what i want to do in a high level.
Apologies for the slightly poor code formatting... (it's mostly pseudocode).
I just can't get this code formatting to work on StackOverflow. It's much easier on Github markdown.

Migrating from Spring configuration from XML file to Annotation

<prop key="load*">PROPAGATION_REQUIRED, readOnly</prop>
Here the key="load*" uses wildcard "*". It matches every function that starts with load right? My question is that; how am I going to implement this using annotation based configuration without placing it on every function?
#Transactional(readOnly = true, propagation= Propagation.REQUIRED)
Is there anyway I can do this without putting this on top of every function which it's name starts with "load"?
Cheers
You can use aspects for this purpose. I.e. define an aspect which intercepts all methods named as "load*" and ensure transaction is started. However in my opinion, such approach is a bad one since it makes your code hard to unit test, understand and maintain further. In fact #Transactional handling is done using aspects, so why bothering to add another layer of abstraction to this? With this annotation someone will look to your code and immediately know that method is/should be running in transaction. Hiding this will make others life harder.
If you still want to implement it, here is small example. NOTE, that I didn't test this at all, just an idea demonstration.
#Aspect
public class MyInterceptor
{
#Around("execution(* load*(..))")
#Transactional
public Object makeMeTransactional(ProceedingJoinPoint pjp)
{
return pjp.proceed();
}
}

How to add a custom ContentHander for JAXB2 support in Spring 3 (MVC)?

Scenario: I have a web application that uses Spring 3 MVC. Using the powerful new annotations in Spring 3 (#Controller, #ResponseBody etc), I have written some domain objects with #XML annotations for marhalling ajax calls to web clients. Everything works great. I declared my Controller class to have a return type #ResponseBody with root XML object - the payload gets marshalled correctly and sent to Client.
The problem is that some data in the content is breaking the XML compliance. I need to wrap this with CDATA when necessary. I saw a POST here How to generate CDATA block using JAXB? that recommends using a custom Content Handler. Ok, fantastic!
public class CDataContentHandler extends (SAXHandler|XMLSerializer|Other...) {
// see http://www.w3.org/TR/xml/#syntax
private static final Pattern XML_CHARS = Pattern.compile("[<>&]");
public void characters(char[] ch, int start, int length) throws SAXException {
boolean useCData = XML_CHARS.matcher(new String(c,start,length)).find();
if (useCData) super.startCDATA();
super.characters(ch, start, length);
if (useCData) super.endCDATA();
}
}
Using Spring MVC 3, how do I achieve this? Everything was "auto-magically" done for me with regards to the JAXB aspects of setup, Spring read the return type of the method, saw the annotations of the return type and picked up JAXB2 off the classpath to do the marshalling (Object to XML conversion). So where on earth is the "hook" that permits a user to register a custom Content Handler to the config?
Using EclipseLink JAXB implementation it is as easy as adding #XmlCDATA to the Object attribute concerned. Is there some smart way Spring can help out here / abstract this problem away into a minor configuration detail?
I know Spring isn't tied to any particular implementation but for the sake of this question, please can we assume I am using whatever the default implementation is. I tried the Docs here http://static.springsource.org/spring-ws/site/reference/html/oxm.html but it barely helped at all with this question from what I could understand.
Thanks all for any replies, be really appreciated.
Update:
Thanks for the suggested answer below Akshay. It was sufficient to put me on right tracks. Investigating further, I see there is a bit of history with this one between Spring version 3.05 and 3.2. In Spring 3.05 it used to be quite difficult to register a custom MessageConverter (this is really the goal here).
This conversation pretty much explains the thinking behind the development changes requested:
https://jira.springsource.org/browse/SPR-7504
Here is a link to the typically required class override to build a cusom solution:
http://static.springsource.org/spring/docs/3.1.0.M1/javadoc-api/org/springframework/http/converter/AbstractHttpMessageConverter.html
And the following Question on stack overflow is very similar to what I was asking for (except the #ResponseBody discussion relates to JSON and jackson) - the goal is basically the same.
Spring 3.2 and Jackson 2: add custom object mapper
So it looks like usage of , and overriding MarshallingHttpMessageConverter is needed, registering to AnnotationMethodHandlerAdapter. There is a recommended solution in link above to also get clever with this stuff and wrap the whole thing behind a custom defined Annotation.
I haven't yet developed a working solution but since I asked the questions, wanted to at least post something that may help others with the same sort of question, to get started. With all due respect, although this has all improved in Spring 3.2, it's still bit of a dogs dinner to get a little customization working... I really was expecting a one liner config change etc.
Rather than twist and bend Spring, perhaps the easiest answer for my particular issue is just to change JAXB2 implementation and use something like Eclipse Link JAXB that can do this out of the box.
Basically you need to create a custom HttpMessageConverter. Instead of relying on the Jaxb2RootElementHttpMessageConverter that spring uses by default.
Unfortunately, customizing one converter means you are telling spring that you will take care of loading all the converters you need! Which is fairly involved and can get complicated, based on whether you use annotations, component scanning, Spring 3.1 or earlier, etc.. The issue of how to add a custom converter is addressed here: Custom HttpMessageConverter with #ResponseBody to do Json things
In your custom message converter you are free to use any custom JAXB2 content handlers.
Another, simpler approach to solve your original problem would be to use a custom XmlJavaTypeAdapter. Create a custom implementation of javax.xml.bind.annotation.adapters.XmlAdapter to handle CDATA, in the marshal method wrap the return value with the cdata braces. Then in your mapped pojo, use the XmlAdapter annotation, pass it the class of your custom adapter and you should be done.
I have not myself implemented the adapter approach, so couldn't provide sample code. But it should work, and won't be a lot of work.
Hope this helps.

Check preconditions in Controller or Service layer

I'm using Google's Preconditions class to validate user's input data.
But I'm worried about where is the best point of checking user's input data using Preconditions class.
First, I wrote validation check code in Controller like below:
#Controller
...
public void register(ProductInfo data) {
Preconditions.checkArgument(StringUtils.hasText(data.getName()),
"Empty name parameter.");
productService.register(data);
}
#Service
...
public void register(ProductInfo data) {
productDao.register(data);
}
But I thought that register method in Service layer would be using another Controller method like below:
#Controller
...
public void register(ProductInfo data) {
productService.register(data);
}
public void anotherRegister(ProductInfo data) {
productService.register(data);
}
#Service
...
public void register(ProductInfo data) {
Preconditions.checkArgument(StringUtils.hasText(data.getName()),
"Empty name parameter.");
productDao.register(data);
}
On the other hand, the method of service layer would be used in just one controller.
I was confused. Which is the better way of checking preconditions in controller or service?
Thanks in advance.
Ideally you would do it in both places. But you are confusing two different things:
Validation (with error handling)
Defensivie Programming (aka assertions, aka design by contract).
You absolutely should do validation in the controller and defensive programming in your service. And here is why.
You need to validate for forms and REST requests so that you can send a sensible error back to the client. This includes what fields are bad and then doing localization of the error messages, etc... (your current example would send me a horrible 500 error message with a stack trace if ProductInfo.name property was null).
Spring has a solution for validating objects in the controller.
Defensive programming is done in the service layer BUT NOT validation because you don't have access to locale to generate proper error messages. Some people do but Spring doesn't really help you there.
The other reason why validation is not done in the service layer is that the ORM already typically does this through the JSR Bean Validation spec (hibernate) but it doesn't generate sensible error messages.
One strategy people do is to create their own preconditions utils library that throws custom derived RuntimeExceptions instead of guava's (and commons lang) IllegalArgumentException and IllegalStateException and then try...catch the exceptions in the controller converting them to validation error messages.
There is no "better" way. If you think that the service is going to be used by multiple controllers (or other pieces of code), then it may well make sense to do the checks there. If it's important to your application to check invalid requests while they're still in the controller, it may well make sense to do the checks there. These two, as you have noticed, are not mutually exclusive. You might have to check twice to cover both scenarios.
Another possible solution: use Bean Validation (JSR-303) to put the checks (preconditions) onto the ProductInfo bean itself. That way you only specify the checks once, and anything that needs to can quickly validate the bean.
Preconditions, validations, whether simple or business should be handled at the filter layer or by interceptors, even before reaching the controller or service layer.
The danger if you check it in your controller layer, you are violating the single responsibility principle of a controller, whose sole purpose is to delegate request and response.
Putting preconditions in service layer is introducing cross cutting concerns to the core business.
Filter or inceptor is built for this purpose. Putting preconditions at the filter layer or in interceptors also allow you to “pick and match” rules you can place in the stack for each servlet request, thus not confining a particular rule to only one servlet request or introduce duplication.
I think in your special case you need to to check it on Service layer and return exception to Controller in case of data integrity error.
#controller
public class MyController{
#ExceptionHandler(MyDataIntegrityExcpetion.class)
public String handleException(MyDataIntegrityExcpetion ex, HttpServletRequest request) {
//do someting on exception or return some view.
}
}
It also depend on what you are doing in controller. whether you return View or just using #ResponseBody Annotation. Spring MVC has nice "out of the box" solution for input/dat validation I recommend you to check this libraries out.
http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/validation.html

parameter validation with net.sf.oval (in play framework)

I would love to use the #NotNull annotation (or #Required or anything) for my own methods. While this works quite well in Controller and Model classes I cant get it to work in my own. This probably is more of a net.sf.oval question then play framework. But it might be connected, I don't know.
I have a class like:
#net.sf.oval.guard.Guarded
public class SimulatorWrapper {
public SimulatorWrapper setRedCode(#play.data.validation.Required #net.sf.oval.constraint.NotNull final String redCode) {
// just gessing here:
if(Validation.hasErrors()) throw new RuntimeException("invalid argument");
if(redCode == null) throw new RuntimeException("null");
// do stuff
return this;
}
}
When I call this method with a null parameter the if throws my exception, but #NotNull and #Required seem to do nothing at all. What am I doing wrong?
The play framework project came with oval 1.5, I downloaded 1.8 and added it to the classpath in eclipse just in case the old one had problems.
I'm starting the server with "play test my-server" and then I navigate to my website (not a test yet, just simple site) with my browser.
Thanks, Alex
P.S. I know the "null is evil" discussion, but I dont have access to the rest of the code so I cant change that.
The validation class is invoked to check the validation annotations by the Play framework only when a controller action is called.
Since you're not in a controller, the Validation on annotation won't be executed and the Required annotion won't be in Validation.hasErrors()
Instead of using annotation, you could use methods like:
Validation.required(redCode); //It'll check for null
And after that, call Validation.hasErrors() and it should work.
However, I don't think you should do this because the errors from Validation.hasError() should come from Validation on the controller action invocation and it can cause you side effects.
If you want to do something like your example, you should not rely on the play Validation class.
Are you sure you're using validation at the right places ?
In case anyone still needs this.
You can do validation with Play annotations in all classes exactly the same way as in controllers.
Just use validate plugin.

Resources