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

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.

Related

How can i share an object between all controllers?

I'm using Spring-Boot and Thymeleaf as a template engine.
I have a web application which has a search input that is accessible in every view to anyone (the search triggers a form submission), the form has a th:object="${searchObject}" attribute and I'm using#RequestBody in my post controller to get the object.
Now, what i did so far was adding a model.addAttribute("searchObject", new SearchObject()) to every controller and it worked just fine but it made me think, what if there is a way to share an object between the whole app that i could declare once and use everywhere .. ?
So i did a little search and found out various solutions that refers to the available contexts in a spring application.
Iv'e tried to implement few of them but couldn't figure out how.
So, is there any simple way of sharing an object between the whole app so it can be accessed inside thymeleaf without writing the same code in every controller?
I'm thinking it should look something like this
th:object="${#sharedObjects.getObjectByName(object)}"
Thanks.
You can use a #ControllerAdvice to add a model attribute in all of your controllers:
#ControllerAdvice
public class SearchObjectModelAttributeAdvice {
#ModelAttribute("searchObject")
public SearchObject searchObject() {
return new SearchObject();
}
}

SmartValidator - manually calling validate with groups

Spring 4.3.2
I need to call SmartValidator.validate() manually and I need it utilize the validation groups that I have defined on the target entity. The javadoc says this...
"This variant of validate() supports validation hints, such as
validation groups against a JSR-303 provider (in which case, the
provided hint objects need to be annotation arguments of type Class)."
void validate(Object target,
Errors errors,
Object... validationHints)
For some reason, I cannot find much information or examples on using "validationHints". So I have been trying things like the following...
validator.validate(targetEntity, errors, new Class[]{ValidationGroup1.class});
validator.validate(targetEntity, errors, ValidationGroup1.class);
So far, it just completely ignores my groupings. It always calls all validators. Any ideas?
Thanks!
===================================
Update: The javadoc also says this..
"Note: Validation hints may get ignored by the actual target
Validator, in which case this method should behave just like its
regular Validator.validate(Object, Errors) sibling."
This sounds like what's happening. But it doesn't give any clue as to why it might ignore it.
Alright then.
It seems the 'answer' is to not use Spring for this. Here is my workaround...
import javax.validation.Validator;
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation> violations = validator.validate(targetEntity, new Class[]{group1.class, group2.class});
Then I convert Set to Spring FieldErrors (since everything is already configured to run Spring). Kind of a clusterf***, but at least it's working now.

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.

Validation on an external model object using play framework 1.2.5

I have a model object which is defined outside of my play application, it is an auto-generated entity produced from wsdl. This means that I can't reliably add validation annotations to its fields. I thought about extending the class and in fact that's what I've done, and I wonder if its possible to add validation tags to the extended version? An immediate problem that I see with that however is that it also has children who's members would also need validation tags added, and if i were to extend them, they would not be used by play's binder. I guess what I need is some kind of custom validator, but from what I can see they are aimed at validation single properties, not entire object models.
Any pointers or suggestions would be great
Cheers!
NFV
You could write custom validator for your class and use:
public static void myController(#CheckWith(MyValidator.class) myParameter)
in controller to test if objects are valid. Then just manually validate them inside MyValidator (it has to extend play.data.validation.Check).
Check play documentation for more info about custom validators.

MVC3: proper place to add a dependency on a logger class?

I have an MVC3 app with a simple Log service. All my services are invoked using Microsoft's Unity Dependency Injection container.
For most methods, I ignore exceptions; they're caught in a top-level error handler, which categorizes them and decides whether or not to log them, generates the HTTP response I desire and calls an action method on the error controller to return my custiom error page.
Sometimes, tho, I don't want to do that; I want to handle the exception where it happens, e.g. in my controller. In that case, I want to log the error before substituting an appropriate default value and continuing with the controller's logic.
I did that in one place: in my controller, I added:
var logService = DependencyResolver.Current.GetService<ILogService>();
try { /* something indeterminate */ }
catch ( Exception ex ) {
logService.LogException(category, ex);
/* do something else instead */
}
Now I want to do it a second time in that controller (as it happens, later in the same method). As soon as I do this again, I see it's time to refactor, as I'm repeating myself.
What's the best way to make my logger available to my controllers? My controllers all inherit from a custom ControllerBase; my first thought is to add it to the ControllerBase's constructor. BUT:
currently I don't have a constructor in the ControllerBase,
I'm a bit worried that referencing the DI container in the
controller breaks the isolation of the controller, negating the
value of DI to begin with, and
I don't think I can pass the
logger in to the ControllerBase's constructor, because (as I
understand it, pls correct me if 'm wrong) controllers can only have
parameterless constructors, so there's no way to pass anything to
them.
Where's the proper place to make the service available to all my controllers?
Place it in your constructor. You can even place it in a BaseController.
Ideally, you will use Dependency Injection and have it come in on your controller. Controllers can have parameters if your IoC container supports it.
private readonly ILogService logService;
public MyController(ILogService logService)
{
this.logService = logService;
}
I wouldn't add it to the base controller for the sole reason that it sounds as if you only use it sporadically. I would add it as Daniel White suggests in the constructor of the controller. If it's looking as though you use it in most controllers, then I'd consider moving it to the base.

Resources