"Enterprise Integration with Spring" certification

Posted by Monik, 13 January 2015.
Programming Java Spring
Preparation for certification

These are my notes I took before taking the Enterprise Integration with Spring Certification exam.

I passed the exam. At the second attempt, after actually taking those notes. The fist attempt was after 1-2 weeks of preparation and it was unnecessarily rushed (I knew it’s too early, if you think it’s too early it’s probably too early), The most difficult thing in preparation for this exam was keeping all those different new things separate in my head and not mixing them up. As soon as I knew where I am in the imaginary table of contents, everything was clear. What helped in organising the knowledge was reading this book.

There is some overlap of this exam with the first Spring Core exam. There is also some stuff that logically would belong to Spring Integration but is actually not part of the exam - the amount of material is simply too big to squeeze everything. That is why it is essential to read the official study guide and study according to it. Or to my notes below (which follow the guide) :P

Table of contents

Remoting

  1. The concepts involved with Spring Remoting on both server- and client-side
    • Exporters on server side, bind a service to registry, or expose an endpoint; no code change to the service
    • ProxyFactoryBeans on client side, which handle the communication and convert exceptions; you inject the instance of service which in in fact a dynamic proxy (polymorphism)
  2. The benefits of Spring Remoting over traditional remoting technologies
    • Hide ‘plumbing’ code
    • Support multiple protocols in a consistent way (normally it’s violation of concerns, business logic mixed with remoting infrastructure)
    • Configure and expose services declaratively (configuration-based approach)
  3. The remoting protocols supported by Spring
    • RMI - uses RMI registry, Java serialisation
    • HttpInvoker - HTTP based (POST), Java serialisation
    • Hessian / Burlap - HTTP based, binary/txt XML serialisation
    • Stateless EJB (not mentioned in the training)

    Server side Client side
    RMI
    <bean class="RmiServiceExporter">
     <p:service-name value="myServiceNameInRegistry"/>
     <p:service-interface value="...TheService"/>
     <p:service ref="myService"/>
     <p:registry-port="1099"/>
    </bean>
    <bean id, class="RmiProxyFactoryBean">
     <p:service-interface value="myService"/>
     <p:service-url value="rmi://foo:1099/myServiceName
    InRegistry"/>
    </bean>
    Http
    Invoker
    <bean name="/transfer" class="HttpInvokerServiceExporter">
     <p:service-interface value="...TheService"/>
     <p:service ref="myService"/>
    </bean>

    + DispatcherServlet or HttpRequestHandlerServlet with name ”transfer
    <bean id, class="HttpInvokerProxyFactoryBean">
     <p:service-interface value="myService"/>
     <p:service-url value="rmi://foo:8080/services/transfer"/>
    </bean>
    Hessian / Burlap
    same as above, replace “HttpInvoker” with “Hessian” / “Burlap”
  4. How Spring Remoting-based RMI is less invasive than plain RMI
  5. Spring HTTP Invoker: how client and server interact with each other

Web Services

  1. How do Web Services compare to Remoting and Messaging
    • information exchange protocol and format is HTTP and XML (or JSON) => no firewalls in between
      • two ways of using the HTTP to transfer XML
        • SOAP/POX and WSDL/XSD -  contract-first, they use only POST and/or GET method for all the operations
        • REST
    • “loose coupling – we define document-oriented contract between service consumers and providers
    • interoperability – XML payload (is understood by all major platforms like Java. NET, C++, Ruby, PHP, Perl,...)”
  2. The approach to building web services that Spring-WS supports
    • is contract-first approach (start with XSD / WSDL)
    • POX / SOAP + WSDL
    • WebServiceClient - support for creating e.g. SOAP message

    SOAP / POX (Spring WS)
    web.xml
    <servlet>
     <servlet-name>si-ws-gateway</servlet-name>
     <servlet-class>
       MessageDispatcherServlet
     </servlet-class>
     <init-param>
       <param-name>contextConfigLocation</param-name>    
       <param-value>si-ws-config.xml</param-value>
     </init-param>
     <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
     <servlet-name>si-ws-gateway</servlet-name>
     <url-pattern>/quoteservice</url-pattern>
    </servlet-mapping>

    * also add contextConfigLocation as context-param and ContextLoaderListener for app context
    web infrastr. config
    <bean class="....UriEndpointMapping">
     <p:name="defaultEndpoint" ref="ws-inbound-gateway"/>
    </bean>
    app config
    <context:component-scan base-package=”transfers.ws”/>
    <ws:annotation-driven/>
    Endpoint implementation
    @Endpoint
    public class TransferServiceEndpoint {
     ...
     @PayloadRoot(localPart=”transferRequest”, namespace=”http://mybank.com/schemas/tr
     public @ResponsePayload TransferResponse newTransfer(@RequestPayload TransferRequest request){
       ...
     }
    }
      • @PayloadRoot defines the resource path, @ResponsePayload and @RequestPayload are for XML mapping
    <int-ws:inbound-gateway id="ws-inbound-gateway"
                           request-channel="ws-requests"
                           extract-payload="false"
                          [marshaller/unmarshaller=”jaxb2”]/>
    
  3. The Object-to-XML frameworks supported by Spring-OXM (or Spring 3.0)
    • JAXB1/2, Castor, XMLBeans, JiBX
    • XStream (not mentioned in training)
    • also XPath argument binding
    <oxm:jaxb2-marshaller
       id=”marshaller”
       contextPath=”reward.ws.types:someotherpackage”/>
    

    , or just simply

    <ws:annotation-driven/> <!-- registers all infrastructure beans needed for annotation-based endpoints, like JAXB2 (un)marshalling-->
    
  4. The strategies supported to map requests to endpoints (?) (link)
    • @PayloadRoot - on method level, requires namespace+localPart values, which build the URL qualifier; needs the PayloadRootAnnotationMethodEndpointMapping registered;
    • SOAP Action Header - based on the To and Action SOAP headers, @SoapAction: on method level “Whenever a message comes in which has this SOAPAction header, the method will be invoked.”
    • <SOAP-ENV::Header>
         ...
         <wsa:To S:mustUnderstand="true">http://example/com/fabrikam</wsa:To>
         <wsa:Action>http://example.com/fabrikam/mail/Delete</wsa:Action>
      </SOAP-ENV:Header>
      
    • WS-Addressing, or AnnotationActionEndpointMapping, also AddressingEndpointInterceptor - annotate the handling methods with the @Action("http://samples/RequestOrder") annotation
    • @Action("http://samples/RequestOrder")
      public Order getOrder(OrderRequest orderRequest) {
         return orderService.getOrder(orderRequest.getId());
      }
      
    • XPath - @Namespace(prefix = "s", uri="http://samples") annotation on class/method level, and @XPathParam("/s:orderRequest/@id") int orderId in the method - the attribute will be given the value which is the evaluation of the XPath expression
    • @PayloadRoot(localPart = "orderRequest", namespace = "http://samples")
      @Namespace(prefix = "s", uri="http://samples")
      public Order getOrder(@XPathParam("/s:orderRequest/@id") int orderId) {
         Order order = orderService.getOrder(orderId);
         // create Source from order and return it
      }
      
    • Message Payload - e.g. @RequestPayload Element inside the method
  5. Of these strategies, how does @PayloadRoot work exactly?
    • it’s written above, but: The PayloadRootAnnotationMethodEndpointMapping uses the @PayloadRoot annotation, with the localPart and namespace elements, to mark methods with a particular qualified name. Whenever a message comes in which has this qualified name for the payload root element, the method will be invoked.“
  6. The functionality offered by the WebServiceTemplate
    • does the SOAP stupid stuff, and also POX
    • works with marshallers / unmarshallers (set the “marshaller” and “unmarshaller” propperty)
    • convenience methods
    • callbacks
    • error handling (annotate method with @SoapFault(faultCode=FaultCode.CLIENT), SoapFaultMessageResolver is default)
    <bean class=”...WebServiceTemplate”>
      <property name=”defaultUri” value=”http://mybank.com/transfer”/>
      <property name=”marshaller” ref=”marshallerAndUnmarshaller”/>
      <property name=”unmarshaller” ref=”marshallerAndUnmarshaller”/>
      <property name=”faultMessageResolver” ref=”myCustomFaultMessageResolver”/>
    </bean>
    
    <bean id=”marshallerAndUnmarshaller” class=”...CastorMarshaller”>
      <property name=”mappingLocation” value=”classpath:castor-mapping.xml”/>
    </bean>
    
    template.marshallSendAndReceive(new TransferRequest(“S123”));
    template.sendSourceAndReceiveToResult(source, result);
    
    full definition, e.g.:
    doSendAndReceive(MessageContext messageContext, WebServiceConnection connection, WebServiceMessageCallback requestCallback, WebServiceMessageExtractor<T> responseExtractor)
    
    • the template by default uses Java's HttpUrlConnectionMessageSender, if you wanna apache client, override "messageSender" with HttpComponentsMessageSender
    • it’s also possible to use JmsMessageSender
  7. The underlying WS-Security implementations supported by Spring-WS (link)
    • are implemented as interceptors
    • XwsSecurityInterceptor (requires Sun JVM and SAAJ) - requires security policy XML configuration file
      • Wss4jSecurityInterceptor (also supports non-Sun JVMs and Axiom)
      • support for Spring Security and JAAS keystores (JAAS goes with wss)
    • also client-side interceptors, which are injected in the WebServiceTemplate
    • supports: authentication, digital signatures, encryption and decryption
    • exception handling: WsSecuritySecurementException (just logs), WsSecurityValidationException (translated to SOAP Fault)
    <ws:interceptors>
     <bean class=”blabla.SoapEnvelopeLoggingInterceptor”
    </ws:interceptors>
    

    or

    <ws:interceptors>
     <ws:payloadRoot localPart=”MyRequest” namespaceUri=”htpp://blabla.com/namespace”>
        <bean class=”blabla.SoapEnvelopeLoggingInterceptor”
     </ws:payloadRoot>
    </ws:interceptors>
    

    client-side:

    <bean class=”org...WebServiceTemplate”>
     <property name=”interceptors”>
       <bean class=”blablabalInterceptor”
     </property>
    </bean>
    
  8. How key stores are supported by Spring-WS for use with WS-Security (?)
    • in Java, the keystores are of type java.security.KeyStore and they store:
      • private keys
      • symmetric keys
      • trusted certificates
    • Spring provides KeyStoreFactoryBean and KeyStoreCallbackHandler
    • <bean id="keyStore" class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean">
          <property name="password" value="password"/>
          <property name="location" value="classpath:org/springframework/ws/soap/security/xwss/test-keystore.jks"/>
      </bean>
      
      <bean id="keyStoreHandler" class="org.springframework.ws.soap.security.xwss.callback.KeyStoreCallbackHandler">
          <property name="keyStore" ref="keyStore"/>
          <property name="privateKeyPassword" value="changeit"/>
      </bean>
      
      <bean id="wsSecurityInterceptor"
          class="org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor">
          <property name="policyConfiguration" value="classpath:securityPolicy.xml"/>
          <property name="callbackHandlers">
              <list>
                  <ref bean="keyStoreHandler"/>
                  <ref bean="...
              </list>
          </property>
      </bean>
      

RESTful services with Spring-MVC

  1. The main REST principles
    • (makes HTTP not only transport protocol, but also application protocol)
    • H Hypermedia (links)
    • U Uniform Interface (nouns for resources, verbs for operations: GET, POST, PUT, DELETE, HEAD, OPTIONS)
    • S Stateless Conversation => scalable
    • I Identifiable Resources
    • R Resource Representations (multiple representations for resource, which is abstract; Accept header in req, Content-Type in res)
    • Method
      Safe (no side effects)
      Indepotent
      Comments
      GET
      y
      y
      Is cacheable (ETag) or Last-Modified, 304
      HEAD
      y
      y

      POST
      n
      n
      Location header in response
      PUT
      n
      y
      Create OR update
      DELETE
      n
      y

  2. REST support in Spring-MVC

    • SOAP / POX (Spring WS)
      web.xml
      <servlet>
       <servlet-name>http-ws-gateway</servlet-name>
       <servlet-class>HttpRequestHandlerServlet</servlet-class>
        <init-param>
          <param-name>contextConfigLocation</param- name>
          <param-value>http-ws-gateway.xml</param-value>
      </servlet>

      <servlet-mapping>
       <servlet-name>http-ws-gateway</servlet-name>
       <url-pattern>/httpquote</url-pattern>
      </servlet-mapping>
      web infrastr. config
      <int-http:inbound-gateway
       id="http-inbound-gateway"
       request-channel="http-request"
       reply-channel="http-response"
       extract-reply-payload="false"
       view-name="about"
       reply-key, reply-timeout,message-converters,
       supported-methods, convert-exceptions,
       request-payload-type, error-code, errors-key,
       header-mapper, name/>

      • name - e.g. "/subscribe", so that it allows it to be used with DispatcherServlet
      • view-name - is the Spring MVC view name
      • you can also use inbound-message-adapter if you don't need two way communication, it uses MessageTemplate
      app config
      N/A
      Endpoint implementation
      @Controller
      @RequestMapping(“/rewards”)
      public class Blabla{

       @RequestMapping(value=”/{number}”, method=GET)
       public String Reward blabla(@RequestBody someObject / Model model, @PathVariable(“number”) String number){
         // ...
         // return view name
       }

       @RequestMapping(method=POST)
       @ResponseStatus(HttpStatus.CREATED)
       public @ResponseBody Reward blabla(@RequestBody someObject, HttpServletResponse res){
         // ...
         res.addHeader(“Location”, getMeUrl(order.getId()));
         // return the object, will be mapped because of @ResponseBody, by converter based on Accept header
       }
      }
    • you can also add e.g. @ResponseStatus(value=HttpStatus.CONFLICT) on your Exception class, to have the exception mapped
    • alternatively to the above, in your controller you can add an empty void method annotated with @ExceptionHandler(value=YourException.class) and @ResponseStatus(value=HttpStatus.NOT_FOUND)
    • <int-http:outbound-gateway
         url="http://blblah"
         request-channel="requests"
         http-method="GET"
         expected-response-type="java.lang.String">
           <int-http:uri-variable
             name="location"
             expression="payload"/>
      </int:http:outbound-gateway>
      
      • you can use outbound-channel-adapter if you don’t need two way communication, it uses RestTemplate;
      • in the case above it’s better to override the error handler, as the default one treats only 4** and 5** responses as errors
    • Spring-MVC is an alternative to JAX-RS, not an implementation
      • got it ;)
    • The @RequestMapping annotation, including URI template support
    • The @RequestBody and @ResponseBody annotations
    • The functionality offered by the RestTemplate
      • for client side
      • has default HttpMessageConverters (same like on server), supports URI templates
        • e.g. Jaxb2RootElementHttpMessageConverter, register it with <mvc:annotation-driven/> !
        • it can also use external configuration, e.g. Apache Commons HTTP Client (set the “requestFactory” property to CommonsCliemtHttpRequestFactory
      • HttpEntity represents request or response (payload + headers)
      <T> T getForObject(URIurl, Class<T>responseType) throws RestClientException;  returns the object from GET
      <T> T getForObject(Stringurl, Class<T>responseType, Object... uriVariables)throwsRestClientException;
      <T> T getForObject(Stringurl, Class<T>responseType, Map<String, ?>uriVariables)throwsRestClientException;
      
      <T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType)
        throws RestClientException;  returns the whole response from GET (with headers)
      
      void put(String url, Object request, Object...uriVariables) throws RestClientException;
      
      void delete(String url, Map<String, ?>uriVariables) throws RestClientException;
      
      <T> T postForObject(String url,Object request,Class<T> responseType, Object uriVariables) throws RestClientException;
      
      <T> ResponseEntity <T> postForEntity(String url, Object request, Class<T> resType, Object...uriVariables)
        throws RestClientException;
      
      * URI url=response.getHeaders().getLocation();  to get location of the new resource!
      
      <T> T execute()
      
      <T> ResponseEntity <T> exchange(String url, HttpMethod method, HttpEntity<?> reqEntity, Class<T> resType, Object... uriVariables)
        throws RestClientException;
      

JMS with Spring

  1. Where can Spring-JMS applications obtain their JMS resources from
    • either create manually (standalone), or obtain from JNDI:
    Destination
    <bean id=”orderQueue” class=”org.apache.activemq...ActiveMQQueue”>
     <constructor-arg value=”queue.orders”/>
    </bean>
    <jee:jndi-lookup id=”orderQueue” jndi-name=”jms/OrderQueue”/>
    ConnectionFactory
    <bean id=”cf” class=”org.apache.activemq.ActiveMQConnectionFactory”>
     <property name=”brokerURL” value=”tc[://localhost:61616”/>
    </bean>
    <jee:jndi lookup id=”cf” jndi-name=”jms/ConnectionFactory”/>
    Connection
    connectionFactory.createConnection();
    Session
    created from the Connection
    JMS Message
    created from Session

    session.createProducer(destination);
    MessageProducer
    MessageConsumer
  2. The functionality offered by Spring's JMS message listener container, including the use of a MessageListenerAdapter through the 'method' attribute in the <jms:listener/> element
    • <div "> MessageListener an interface for asynchronous reception of messages; one method: void onMessage(Message) </div>
    • implement MessageListener, or SessionAwareMessageListener (extends MessageListener)
    • requires a listener container - in the past EJB container, now
      • SimpleMessageListenerContainer - fixed number of sessions
      • DefaultMessageListenerContainer - adds transactional capability
    <jms:listener-container connection-factory=”cf”>
    <jms:listener destination=”queue.orders”
                  ref=”myListener
                  (method=”order”)
                  (response-destination=”queue.confirmation”)/>
    </jms:listener-container>
    
  3. The functionality offered by the JmsTemplate
    • converts exceptions to unchecked
    • convenience methods
    • needs reference to ConnectionFactory, optionally set defaultDestination property
      • use CachingConnectionFactory wrapper around the ActiveMQConnectionFactory, as JmsTemplate aggresively opens and closes and reopens JMS resources
    • uses
      • MessageConverter (default SimpleMessageConverter - handles String, Serializable, Map, byte[]) - from/to Message
      • DestinationResolver (default DynamicDestinationResolver, JndiDestinationResolver)- from String to Destination
    void convertAndSend([String/Destination d,] Object m)
    void convertAndSend(Object m, MessagePostProcessor mpp) // to do stuff to the message after it has been converted
    void send(MessageCreator mc) // is used inside convertAndSend()
    
    Object execute(ProducerCallback<T> action)
    Object execute(SessionCallback<T> action)
    
    Message receive([String/Destination d,])
    Object receiveAndConvert(destination)
    

Transactions

  1. Local JMS Transactions with Spring
    • acknowledge mode - not transactions connection.createSession(transacted=false, acknowledgeMode)
      • AUTO_ACKNOWLEDGE (default) => calling .receive() or onMessage() = removing message from the queue
      • CLIENT_ACKNOWLEDGE => client must call message.acknowledge(), and this one call will remove all messages since last time! (which are bound to the same session). And client can also call session.recover() to have redelivery of those messages (can be duplicates)
      • DUPS_OK_ACKNOWLEDGE => like auto but lazily, once every few times
    • transacted session - connection.createSession(transacted=true, null)
      • starts local JMS when no managed JMS or JTA transaction is in progress; will be synchronised with existing local transaction
      • transaction starts, when message is received
      • if a message fails, it will be put back on the queue
  2. How to enable local JMS transactions with Spring's message listener container
  3. <jms:listener-container acknowledge=”auto|client|dups_ok|transacted”/>
    

    or

    <jms:listener-container transaction-manager=”tm”/>
    
    connection.createSession(transacted=true, acknowledgeMode);
    session.commit();
    session.rollback();
    
  4. If and if so, how is a local JMS transaction made available to the JmsTemplate
    • <bean class=”..JmsTemplate>
         (<property name=”sessionAcknowledgeMode” value=”...”/>)
         <property name=”sessionTransacted” value=”true”/>
      </bean>
      
    • jmsTemplate will automatically use same session (ConnectionFactoryUtils.doGetTransactionalSession()), so the above settings are ignored in case the session was created within an active transaction already
  5. How does Spring attempt to synchronize a local JMS transaction and a local database transaction (?)
    • Commit database before JMS (can end up with duplicates), and at the end
    • Put commits close together
    • only as last resort use XA
  6. The functionality offered by the JmsTransactionManager (?)
    • JmsTransactionManager or DataSourceTransactionManager are both implementations of PlatformTransactionManager
    • “Performs local resource transactions, binding a JMS Connection/Session pair from the specified ConnectionFactory to the thread
    • The JmsTemplate auto-detects an attached thread and participates automatically with Session
    • The JmsTransationManager allows a CachingConnectionFactory that uses a single connection for all JMS access (performance gains). All Sessions belong to the same connection”
  7. What guarantees does JTA provide that local transactions do not provide
    • once-and-once-only delivery
    • ACID with multiple resources
  8. How to switch from local to global JTA transactions
  9. <jms:listener-container transaction-manager=”transactionManager” ../>
    
    • you also may have to reconfigure some resources like Hibernate
  10. Where can you obtain a JTA transaction manager from
    • within J2EE server:
    • <tx:jta-transaction-manager/>
      
      <jee:jndi-lookup id=”dataSource” jndi-name=”java:comp/env/jdbc/myDS”/>
      <jee:jndi-lookup id=”connectionFactory” jndi-name=”java:comp/env/jdbc/myConnFac”/>
      
    • standalone definition:
    • <bean id=”transactionManager” class=”org….JtaTransactionManager”>
       <property name=”transactionManager” ref=”jtaTxMgr”/>
       <property name=”userTransaction” ref=”userTx”/>
      </bean>
      
    • this class is provided by Spring, but it only integrates with external JTA TX manager (e.g. Atomikos was used in course)
    • the externally provided transactionManager and userTransaction resources have to be of type “XA aware”

Batch processing with Spring Batch

  1. Main concepts (Job, Step, Job Instance, Job Execution, Step Execution, etc.)
    • easy, see also here
    • job execution has status, but job instance (job+parameters) also has a status, the “overall status”
    • <job id="resendUnprocessedDinings">
       <step id="processConfirmationsStep" next="sendUnprocessedDiningsStep">
         <tasklet>
           <chunk reader="confirmationReader"
                  writer="confirmationUpdater"
                  commit-interval="${chunk.size}"
                  reader-transactional-queue="true"/>
         </tasklet>
       </step>
      </job>
      
  2. The interfaces typically used to implement a chunk-oriented Step
    • Step for one chunk goes like this:
      • ItemReader,  ItemReader<Dining>, public Dining read(){}
      • ItemProcessor (optional), ItemProcessor<XMLDining, Dining>, public Dining process(XMLDining bla){}
      • ItemWriter, ItemWriter<Dining>, public write(List<? extends Dining> dinings){}
      • <bean id="itemReader" class="....FlatFileItemReader" scope="step">
         <property name="resource" value="file://#{jobParameters['filena']}"/>
         <property name="lineMapper">
           <bean class="....DefaultLineMapper">
             <property name="lineTokenizer">
               <bean class="....DelimitedLineTokenizer">
                 <property name="names" value="source,dest,amount,date"/>
               </bean>
             </property>
             <property name="fieldSetMapper" ref=”myMapper”/>
           </bean>
         </property>
        </bean>
        
        <bean id="itemWriter" class="....FlatFileItemWriter" scope="step">
         <property name=”fieldSetCreator” ref=”customCreator”/>
         ...
        </bean>
        
  3. How and where state can be stored
    • in JobRepository
      • it can use database or in  memory map
      • persists  jobs’ metadata and intermediate state of execution (=job instance and job execution)
      <batch:job-repository id=”jobRepository”/>
      

      , or

      <batch:job-repository
             data-source="dataSource"
             id="jobRepository"
             transaction-manager="transactionManager"
             table-prefix="BATCH_"/>
      
    • JobLauncher creates JobExecution entity in the JobRepository, next it executes the job, and returns the result
    • JobLauncher is already wrapped in CommandLineJobRunner, if you wanna use it
    • jobLauncher.run(job, parameters)
    • <bean id="jobLauncher" class="....SimpleJobLauncher">
        <property name="jobRepository" ref="jobRepository"/>
      </bean>
      
  4. What are job parameters and how are they used
    • they identify the job instance, same instance cannot be run twice thats why add there some counter
    • in case same job instance is attempted to be re-launched you will get JobInstanceAlreadyCompletedException
    • you create it programmatically using builder:  
    • JobParametersBuilder jpb = new JobParametersBuilder();
      jpb.addString('filena', 'payment.xml');
      JobExecution execution = jobLauncher.run(job, jpb.toJobParameters());
      
  5. What is a FieldSetMapper and what is it used for
    • FieldSetMapper<T> → T mapFieldSet(FieldSet fs)
    • used by e.g. LineMapper (e.g. DefaultLineMapper), which is used by FlatFileItemReader
    • Date date = fs.readDate(0,"dd/MM/yyyy");
      Long number = fs.readLong(1);
      String value = fs.readString("city");
      String[] values = fs.getValues();
      
          public class MyMapper implements FieldSetMapper<Payment>{
           @Override
           public Payment mapFieldSet(FieldSet fieldSet)
                throws BindException {
              ... = fieldSet.readString("source");
              ... = fieldSet.readBigDecimal("amount");
              ... = fieldSet.readDate("date");
           }
          }
      

Spring Integration

  1. Main concepts (Messages, Channels, Endpoint types)
  2. Pay special attention to the various Endpoint types and how they're used!
    • refer even more carefully the above
  3. How to programmatically create new Messages
    • MessageBuilder of course
    • each message is created with unique ID
    • Also MessagingTemplate is worth mentioning, which is a programmatic endpoint for sending the messages created by MessageBuilder (e.g. for testing)
  4. Using chains and bridges
    • see a.
  5. Synchronous vs. asynchronous message passing: the different Channel types and how each of them should be used
    • see a.
  6. The corresponding effects on things like transactions and security
    • see a.
  7. The need for active polling and how to configure that

Comments


Comments: