Announcement Announcement Module
Collapse
No announcement yet.
MethodEndpoint and Validators Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • MethodEndpoint and Validators

    Hi

    I have a design related question: is it possible somehow to integrate MethodEndpoint with Validators, i.e business validation not xsd schema validation?

    I would like to have a MethodEndpoint that operates on unmarshalled xml (java object ) and before executing its method invoke appropriate Validator.

    I' have been looking in reference guide and javadocs and i haven't found anything like it. Validators are tied to AbstractValidatingMarshallingPayloadEndpoint not MethodEndpoints.


    The task i have is to create about 15 endpoints - i have 15 request-response pairs.

    Some of these request need business validation and others don't. I found using the PayloadRootAnnotationMethodEndpointMapping along with GenericMarshallingMethodEndpointAdapter and JaxbMarshaller very useful and producitve. The one issue missing in this scenario is business validation.

    I know i could do it manually , i.e. invoke proper validation in endpoint method.
    Another idea i have is to create proxy around my @endpoint class and have it execute validation before invoking endpoint method.

    But maybe there is some out-of-box clear solution for the problem.
    Last edited by miluch; Jul 18th, 2008, 06:22 AM. Reason: typo

  • #2
    Hi,

    Could you do this with an interceptor? See the EndpointInterceptor interface:

    Processes the incoming request message. Called after {@link EndpointMapping} determined an appropriate endpoint.

    boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception;

    If you implement this interface you can add the business validation logic into it. The interceptors are injected into the endpointmapping.

    Comment


    • #3
      Hi

      I could do validation in interceptor but it implies 2 issues i would like to avoid:
      1) Interceptors are associated to EndpointMappings not to Endpoint itself.
      So for MethodEndpointMapping validatorInterceptor need to validate all input messages that are handled by this EndpointMapping,finally you will get multiple if statements.
      2) Interceptors are invoked before unmarshalling process, it means that validatorInterceptor will need cope with some form of XML representation.

      miluch



      Originally posted by jethrobakker View Post
      Hi,

      Could you do this with an interceptor? See the EndpointInterceptor interface:

      Processes the incoming request message. Called after {@link EndpointMapping} determined an appropriate endpoint.

      boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception;

      If you implement this interface you can add the business validation logic into it. The interceptors are injected into the endpointmapping.

      Comment


      • #4
        what solution did you come up with? i'm need the same type of validation using the same configuration.

        Comment


        • #5
          I finally decided not to use MethodEndpoint and use MessageEndpoint instead since I didn't feel comfortable to play with (raw) XML.

          Comment


          • #6
            so how did you wire in your validator? did you write custom one or re-used the spring one?

            you don't have to deal with XML in the methodEnpoint using @PayloadRoot. in my case jaxb is converting to a java object.

            Comment


            • #7
              Hi

              When i started this post i was unaware of MarshallingMethodEndpointAdapter.
              This fact and the lack of built-in validation support of @EndPoint annotated endpoints made me use AbstractValidatingMarshallingPayloadEndpoint.
              Following this way i got automatic marshalling and validation at the cost of using PayloadRootQNameEndpointMapping with its verbose XML configuration...

              I haven't played much with SWS lately so maybe there are better options but for your case i would think of extending MarshallingMethodEndpointAdapter.
              You could base on AbstractValidatingMarshallingPayloadEndpoint:
              After unmarshalling request, call validator,call endpoint,...

              If you wanna to have a single validator for a single request (i.e. endpoint method) - as i always try to keep it - you will have to think of a way to determine which validator use for which request. You could do either:
              wire all validators to your new MarshallingMethodEndpointAdapter, iterate over them and check if any of them supports unmarshalled object class ( org.springframework.validation.Validator#supports( ) approach)
              or
              you could create your own annotation like: @ValidatedBy("myValidator") with value corresponding to bean name of validator to use.

              Still there are some corner cases: what if in some scenario you wanna to continue processing (call method endpoint) if validation failed (take a look at if AbstractValidatingMarshallingPayloadEndpoint#onVal idationErrors)

              Hope it helps

              Comment


              • #8
                it appears with 1.5.9 that you either get validators and one class for each method for our service with a lot of xml or you get a single class with all the method in it that's annotated. life would be so much easier if there was a @Validation annotation that you could map a validator to method endpoint.

                so what i've done is this,.

                Code:
                    private void validateBusinessRules(TowRequest request, String objName, Class errorBindingClass) {
                        //@SuppressWarnings({"ThrowableInstanceNeverThrown"})
                        Errors errors = new BindException(errorBindingClass, objName);
                        _towWebServiceValidator.validate(request, errors);
                        if (errors.hasErrors()) {
                            StringBuffer errorMsg = new StringBuffer();
                            for (ObjectError objectError : errors.getAllErrors()) {
                                errorMsg.append(objectError.getCode()).append(" : ").append(objectError.getDefaultMessage()).append("\n");
                            }
                            throw new TowWebServiceException("Validation Erorrs:\n" + errorMsg);
                        }
                    }
                this method is the first thing that's call in each of my method endpoints.
                my ServiceValidator is a factory that figures out what type of validator i need and invokes my validation.

                Comment


                • #9
                  Originally posted by denov View Post
                  it appears with 1.5.9 that you either get validators and one class for each method for our service with a lot of xml or you get a single class with all the method in it that's annotated.
                  I think you are right, scanning through SWS source i found only 2 classes that have "Validating" in its names: AbstractValidatingMarshallingPayloadEndpoint,
                  AbstractValidatingInterceptor. So it seems that AbstractValidatingMarshallingPayloadEndpoint is the only one Endpoint with built-in execution of validators.
                  As i mentioned above it should not be hard to create your own annotation based solution. It would look concisely and would help you to have your business validation executed from a single point of code (now you must execute validateBusinessRules manually at the beginning of each methodendpoint).

                  Aside:I am wondering if you could call validateBusinessRules from your own custom EndpointAdapter or maybe use Spring AOP to proxy each of request handling methods

                  Comment

                  Working...
                  X