Daniel Gulyas opened SPR-15314 and commented
Quick summary
Hi!
It would be really cool if the Validator implementations could be reused at the Service level hassle-free.
It would be cool because: * It's a common scenario that there's a second request source using the same dto (think webmvc / rest and mq), adding the second source involves extra work if it doesn't provide the binding in an other way, without using implementations of the Errors interface * Increases code reuse, since we use the same Validator on both Service-level and Controller-level * Would promote validation at the service-level a bit
Example scenario when that happens:
1. There's a web-mvc project, controller <-dto-> service
, at the controller-side the dto is validated with the Validator
2. There's a business need to implement a secondary source of requests (let's say an mq)
Now there's a possibility to reuse the Validator created for the controller at the service level, but for me it seems to involves quite a hassle, it would be nice to make that convenient.
Proposal
- Create an interface which implements the simplified Errors interface
- Can be instantiated with the target object only
- Doesn't necessary have to store all the rejected properties, tracking if there was any errors might be enough
- Create an abstract class which implements Validator
- Boolean validate(Object target) is implemented here
The namings for me seem to be a bit weak, they could handle suggestions I'm pretty sure.
For existing Validator implementations there's only need to extend this abstract class and it'll turn into a validator which is convenient to use at the service level, please see the attached java files, this might be a bit invasive although.
Follow-up
This is just an idea and i'm kinda new to Spring and to Java in general so the proposal will probably include foolish design mistakes, i looked it up and so far i haven't seen anything which would make reusing of these easy, please point it out if there's already some.
If that's cool to do and there's a consensus i could make a pr for this in the coming days.
Let me know what you think!
Attachments: - ExampleValidator.java (553 bytes) - ServiceLevelValidator.java (350 bytes) - SimplifiedErrors.java (488 bytes)
Comment From: jhoeller
We are considering a default method on the Validator
interface for such a purpose in 6.1, for simplified assertion-style invocations. We are not sure whether to reduce this to a boolean
return value or rather throw an IllegalArgumentException
with a rich message, but either way, we're going to make it easier to invoke a Validator
without an Errors
instance having to be manually built/provided.
Comment From: jhoeller
After a bit of back and forth, I'm introducing a Validator.validateObject(Object)
method with an Errors
return value now which can easily be used for a Validator.validateObject(Object).hasErrors()
check but also with a new failOnError method on the Errors
interface: Validator.validateObject(Object).failOnError(IllegalStateException::new))
. Underneath the covers, this is using a new SimpleErrors
implementation which tracks registered errors in a lean fashion and flexibly accesses field values via getter methods or raw field access (while not providing any binding support).