Skip to main content

@Marshalled Annotation

The @Marshalled annotation is a class-level annotation in org.apache.juneau.marshall that controls how a class is serialized and parsed across all Juneau marshalling formats (JSON, XML, HTML, MessagePack, and the rest).

It is the format-side counterpart to @BeanType. @Marshalled carries the marshalling-only attributes — marshalling strategy, type naming, bean dictionary, implementation class, interceptors, POJO examples, and wire-format overrides — while the bean-modeling attributes (properties, excludeProperties, findFluentSetters, interfaceClass, stopClass, propertyNamer, unsorted, ...) live on @BeanType in juneau-commons.

@Marshalled(typeName="address")
public class Address {
public String street;
public String city;
}
Migration

Prior to the 10.0 refactor, the bean-modeling members now on @BeanType were part of @Marshalled. @Marshalled retains only the marshalling-layer attributes documented below; see @BeanType Annotation for the model side.

Serialize / Parse Round-Trip​

@Marshalled participates transparently in every marshaller. Here the example attribute supplies a canonical POJO example, and the type round-trips through JSON5:

@Marshalled(example="{street:'123 Main St',city:'Springfield'}")
public class Address {
public String street;
public String city;
}

Address a = new Address();
a.street = "123 Main St";
a.city = "Springfield";

// Serialize.
String json = Json5.DEFAULT.of(a); // {street:'123 Main St',city:'Springfield'}

// Parse back.
Address a2 = Json5.DEFAULT.to(json, Address.class);

Marshalling Strategy: as​

The @Marshalled(as) attribute selects the marshalling strategy from the MarshalledAs enum. The default is MarshalledAs.DETECT (auto-detection). Use MarshalledAs.STRING to serialize via toString() and parse via a fromString/valueOf/single-String constructor — the declarative replacement for the old MarshallingStringSwap pattern.

// Serialize/parse this type as a single string value.
@Marshalled(as=MarshalledAs.STRING)
public class PhoneNumber {
private final String value;
public PhoneNumber(String value) { this.value = value; } // single-String constructor for parsing
@Override public String toString() { return value; } // used for serialization
}

See @MarshalledAs Enum for full details.

Type Naming: typeName / typePropertyName​

typeName assigns a dictionary name to a class so the serializer can emit a type discriminator when the static type is ambiguous (for example, a property declared as Object), and the parser can resolve the concrete class from that name. typePropertyName overrides the property used to hold the discriminator (default _type).

@Marshalled(typeName="cat")
public class Cat extends Animal {}

@Marshalled(typeName="dog", typePropertyName="kind")
public class Dog extends Animal {}

When a Cat is serialized through a property of the base Animal type, the output includes _type:'cat' so it can be parsed back to the correct subclass. See Bean Dictionaries for how type names are registered and resolved.

Bean Dictionary: dictionary​

The @Marshalled(dictionary) attribute registers the set of classes that make up the bean dictionary for all properties in this class and its subclasses. Combined with typeName, this lets polymorphic properties round-trip.

@Marshalled(dictionary={Cat.class, Dog.class})
public class Pet {
public Animal animal; // resolved to Cat or Dog via _type on parse
}

The dictionary can also be registered globally on the marshalling context:

WriterSerializer serializer = JsonSerializer
.create()
.beanDictionary(Cat.class, Dog.class)
.build();

See Bean Sub Types for a worked subtype example.

Implementation Class: implClass​

For interfaces and abstract classes, @Marshalled(implClass) specifies the concrete class to instantiate during parsing.

@Marshalled(implClass=MyInterfaceImpl.class)
public interface MyInterface { ... }

Bean Interceptor: interceptor​

The @Marshalled(interceptor) attribute registers a BeanInterceptor that can transform property values in transit — rewriting values on read (serialize) and write (parse).

// Redact a sensitive property on serialization.
public class AddressInterceptor extends BeanInterceptor<Address> {
@Override
public Object readProperty(Address bean, String name, Object value) {
return "taxInfo".equals(name) ? "redacted" : value;
}
}

@Marshalled(interceptor=AddressInterceptor.class)
public class Address {
public String getTaxInfo() { ... }
public void setTaxInfo(String value) { ... }
}

POJO Example: example​

The @Marshalled(example) attribute supplies an example instance of the class in JSON5 (Simplified JSON) format. Examples are surfaced in generated Swagger/OpenAPI documents. The value supports VarResolver.DEFAULT substitution (e.g. $C{myConfigVar}).

@Marshalled(example="{foo:'bar',baz:123}")
public class MyClass { ... }

The same example can be defined in code with the @Example annotation on a static field or method — see @Example Annotation.

Wire-Format Overrides​

@Marshalled can override the default wire format for common datatypes on a per-class basis. Each override defaults to NOT_SET (inherit the context default). The available attributes are:

AttributeApplies toEnum
calendarFormatCalendarCalendarFormat
dateFormatDateDateFormat
durationFormatDurationDurationFormat
temporalFormatjava.time.*TemporalFormat
localeFormatLocaleLocaleFormat
timeZoneFormatTimeZoneTimeZoneFormat
binaryFormatbyte[]BinaryFormat
enumFormatenumsEnumFormat
uuidFormatUUIDUuidFormat
bitSetFormatBitSetBitSetFormat
bigNumberFormatBigInteger / BigDecimalBigNumberFormat
booleanFormatBoolean / booleanBooleanFormat
floatFormatFloat / Double (non-finite)FloatFormat
currencyFormatCurrencyCurrencyFormat
classFormatClassClassFormat
periodFormatPeriodPeriodFormat
// Serialize byte[] values as hex and enums as lower-hyphenated names for this class.
@Marshalled(binaryFormat=BinaryFormat.HEX, enumFormat=EnumFormat.LOWER_HYPHEN)
public class MyBean {
public byte[] data;
public MyEnum status;
}

Applying to REST Classes and Methods​

The same attributes can be applied in bulk to third-party classes without annotating them directly, using @MarshalledConfig (with on/onClass) on @Rest-annotated classes and @RestOp-annotated methods via @MarshalledApply.

See Also

The Java doclink docs/topics/MarshalledAnnotation on Marshalled.java resolves to this page.