Processing lifecycle
Every incoming HTTP POST follows these stages:Metadata capture
AS4XServletHandler.createIncomingMessageMetadata() creates an AS4IncomingMessageMetadata object populated with transport-level data: remote IP, host, port, authenticated user, cookies, HTTP headers, and any TLS client certificates.SOAP / MIME parsing
AS4IncomingHandler.parseAS4Message() reads the Content-Type header. For multipart/related it splits the MIME parts: the first part is the SOAP envelope, subsequent parts are attachments. For plain SOAP the entire body is parsed as XML.SOAP header processing
Each registered
ISoapHeaderElementProcessor is invoked in order. The WSS4J processor verifies the WS-Security signature and decrypts the payload. The EBMS3 processor extracts the eb:Messaging header into the message state.Profile validation
If an AS4 profile is active (e.g. Peppol), the validator checks P-Mode compliance, user message structure, and initiator identity against the signing certificate.
Attachment decompression
Compressed attachments (GZIP via AS4 compression feature) are transparently decompressed. The
MimeType part property is used to restore the original MIME type.Duplicate detection
The message ID is checked against the in-memory duplicate store. Duplicate messages are rejected with an EBMS error. The store is cleaned up periodically by
AS4DuplicateCleanupJob according to phase4.incoming.duplicatedisposalminutes.SPI dispatch
All registered
IAS4IncomingMessageProcessorSPI implementations are called. For user messages processAS4UserMessage() is invoked; for signal messages (receipts, errors, pull-requests) processAS4SignalMessage() is invoked.IAS4IncomingMessageMetadata
IAS4IncomingMessageMetadata carries transport-level information about one incoming request. It is passed to every SPI callback so your handler can log, audit, or make routing decisions based on connection properties.
Accessing metadata in a handler
Accessing the SBDH payload (Peppol)
For Peppol messages,Phase4PeppolServletMessageProcessorSPI extracts the Standard Business Document (SBD) from the first attachment and calls your IPhase4PeppolIncomingSBDHandlerSPI with the pre-parsed objects.
Duplicate detection
phase4 automatically tracks AS4 message IDs. If the same message ID arrives a second time, it is rejected with an EBMS error (EBMS:0202 - Other) and no SPI callbacks are invoked.
The duplicate store is backed by the MetaAS4Manager and cleaned up by AS4DuplicateCleanupJob. The retention period is controlled by:
AS4ServerInitializer.initAS4Server() and stopped by AS4ServerInitializer.shutdownAS4Server().
Receipt generation
Receipts are generated automatically byAS4RequestHandler when:
- The incoming message is a user message (not a signal message).
- The P-Mode specifies a reply pattern that requires a synchronous receipt.
- All
IAS4IncomingMessageProcessorSPIimplementations return a success result.
eb:SignalMessage containing an eb:Receipt element. It is written directly into the HTTP response of the same connection.
Your SPI can inspect the outgoing receipt via processAS4ResponseMessage():
Error handling
Returning an EBMS error from a SPI
Add errors to theaProcessingErrorMessages list and return AS4MessageProcessorResult.createFailure():
Throwing an exception
Throwing any exception from an SPI method is treated as a failure. phase4 logs the exception and returns an EBMS error signal to the sender. For Peppol handlers, throwing fromhandleIncomingSBD() produces the same result — the AS4 layer catches it and converts it into an EBMS_OTHER error.
HTTP error responses
Phase4 maps internal errors to HTTP status codes as follows:| Condition | HTTP status |
|---|---|
Phase4Exception (bad request) | 400 Bad Request |
SOAP mustUnderstand header not processed | 500 (per SOAP spec) |
| Any other unhandled exception | 500 Internal Server Error |