Configuring HAPI

HAPI has a number of configurable properties which may be used to customize the way it operates.

System Properties

A number of settings are set using system properties. A future release, hopefully before long, will deprecate these properties and move to runtime flags which may by configured by individual instances of the HAPI parser and other components.

An issue has been opened to track this task.

HAPI Context

HAPI can be configured by using one or more instances of HapiContext, particularly its default implementation DefaultHapiContext. The HAPI Context is the "single point of contact" for configuring HAPI parsers, validators, and server components. It furthermore provides factory methods that obtain parsers, validators etc. that are corresondingly configured:

HapiContext context = new DefaultHapiContext();
context.setDefaultModelClassFactory(new MyOwnModelClassFactory());
PipeParser parser = context.getPipeParser();

This code snippet modifies the default configuration by using a custom ModelClassFactory. The obtained PipeParser is then configured to use this ModelClassFactory.

Other configuration items include ValidationRuleBuilder, ValidationContext and ParserConfiguration (see below).

HAPI Parser

The HAPI Parser may be configured using a ParserConfiguration object.

The ParserConfiguration is a bean which sets and retrieves parser configuration properties and may be shared among multiple parser instances.

Default behaviour for OBX-2

In a normal OBX (Observation) segment, OBX-2 provides the datatype to be applied to OBX-5. So, for instance if an OBX repetition was conveying a timestamp (TS), it might look like:


If the OBX-2 value is missing (which sometimes happens because of a misbehaving sending system), you may see an error such as "OBX-5 is valued, but OBX-2 is not. A datatype for OBX-5 must be specified using OBX-2".

In this case, you may specify that HAPI should use a default type when none is found by specifying a default OBX-2 type:

ORU_R01 parsedMessage = (ORU_R01)parser.parse(someInvalidMessage);

If the OBX-2 value is invalid, meaning that it has a value but that value is not a valid HL7 datatype (e.g. "String" instead of "ST"), you may specify a default type to assume if the OBX-2 value can not be understood.

ORU_R01 parsedMessage = (ORU_R01)parser.parse(someInvalidMessage);

See the JavaDoc for examples.

Forced Encoding

By default, when encoding a message HAPI will not encode any segments or fields that have no content and therefore have no semantic meaning in the message.

This can cause problems if you need to transmit a message to a system that expects certain empty content to be present in order to get "hints" about where in the message it is.

The addForcedEncode method may be used to add Terser paths which should be forced to be encoded:

// ORC-4 will still exist (but be empty) even if ORC has no content
String encoded = parser.encode(message);

See the JavaDoc for examples.

Message ID generation

Under some circumstances HAPI creates a HL7 message, e.g. an Acknowledgement message, which is already populated with data. In this case, a unique message ID must be written into the MSH-10 field. HAPI provides a number of IDGenerator implementations that can be used for this purpose. By default, a file serves as persistent storage of the ID, so that in case of restarts no duplicate IDs are assigned.

You can choose one of the other ID generators or even provide your own implementation.

parser.getParserConfiguration().setIdGenerator(new InMemoryIDGenerator())

Unexpected Segment Behaviour

If you are processing messages with nonstandard segments (e.g. Z-segments), the parser by default will add them where it finds them. You can configure the parser to always add them to the root message structure instead of inline in the current group: