How to use SpEL to read payload and header content

2019-08-21 10:28发布

问题:

Technologies in my project

Spring Boot 2
Spring Integration (XML style)
Java 8
Tomcat 9.x/Liberty 19.0.0.1

As a part of my Spring Integration project (REST API with an inbound-http-gateway, that takes an XML input and produces an XML output), I am writing the following components:

  1. A service-activator that performs basic validation of the incoming XML against its XSD.
  2. If validation is successful, a POJO (a builder-pattern Java object) is built with a Boolean instance variable/property called "isError" set to true.
  3. If validation is un-successful, the POJO (a builder-pattern Java object) is built with a Boolean instance variable/property called "isError" set to false.
  4. After building the POJO, it is wrapped into a Message and sent to an output-channel.
  5. There is a router component that gets the message from the outout-channel and decides the target route/channel based on the value of the "isError" property in the payload/POJO.

A draft of the POJO class (in reality, the POJO will have more properties but for our example, kept it short):

public class Composite {
    private Boolean isError;

    private Composite(CompositeBuilder compositeBuilder) {
            this.isError = miCompositeBuilder.isError;
        }

    public boolean isError() {
            return isError;
        }

    //Builder
    public static class CompositeBuilder {
        private Boolean isError;

        public CompositeBuilder(Boolean isError) {
            this.isError = isError;
        }      

        public Composite build() {
            return new Composite(this);
        }
    }
}

The validator service-activator component in XML:

<!-- SERVICE ACTIVATOR FOR REQUEST VALIDATION -->
    <int:service-activator ref="myService"
                           method="validateMYRequest"
                           input-channel="myGatewayRequests"
                           output-channel="compositesPostRequestValidation" />

The router component in XML:

<!-- ROUTER POST-REQUEST VALIDATION -->
    <int:router input-channel="compositesPostRequestValidation" expression="payload.isError">
        <int:mapping value="true" channel="upstreamResponses"/>
        <int:mapping value="false" channel="downstreamValidatedRequests"/>
    </int:router>

Finally coming to my questions, in this "router",

  • Question 1) Something seems to be wrong with the SpEL expression (payload.isError) since I got an exception during the invocation of the router that went like:

    org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'isError' cannot be found on object of type 'com.amb.restSample.core.model.Composite' - maybe not public or not valid? at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:217) ~[spring-expression-5.1.5.RELEASE.jar:5.1.5.RELEASE] ... ...

Can you please tell me how to access the Boolean "isError" property inside the Composite POJO? This is assuming that the Message being sent to the router is Message

  • Question 2) In case I wish to accommodate the "isError" property as a Message header (String) before sending it to the router (instead of using it as a Boolean property inside the Composite POJO), is there an expression to access it?

回答1:

Looks like the paylaod is MIComposite not Composite.

In any case, SpEL uses the JavaBean conventions; so isError() is a getter for a boolean property error. So payload.error should work (as long as MIComposite exposes it). Or you can use payload.isError().

If it's in a header, the expression would be headers['myHeader'].