Skip to main content

Session Options via HTTP

Juneau REST supports overriding serializer and parser session properties on a per-request basis via HTTP headers or query parameters. This allows clients to control aspects of marshalling (such as whitespace formatting, bean type annotations, etc.) without server-side code changes.

Overview​

The feature works at two levels:

  1. Server-side: Configure which properties clients are allowed to override using @Rest or @RestOp annotations.
  2. Client-side: Send the allowed properties via HTTP headers or query parameters.

Server Configuration​

@Rest Level (applies to all operations in the class)​

@Rest(
serializers=JsonSerializer.class,
parsers=JsonParser.class,
allowedSerializerOptions={"useWhitespace", "addBeanTypes", "sortCollections"},
allowedParserOptions={"trimStrings", "validateEnd"}
)
public class MyResource extends BasicRestServlet {
@RestGet
public MyBean get() { ... }
}

@RestOp Level (applies to a specific operation)​

@RestGet(
allowedSerializerOptions={"useWhitespace"},
allowedParserOptions={"trimStrings"}
)
public MyBean get() { ... }

Overriding Inheritance with noInherit​

By default, operation-level allowedSerializerOptions and allowedParserOptions are merged with class-level values. Use noInherit to override and replace the parent values:

@Rest(allowedSerializerOptions={"useWhitespace", "addBeanTypes"})
public class MyResource extends BasicRestServlet {

// Only allows "sortCollections" - ignores parent "useWhitespace" and "addBeanTypes"
@RestGet(
allowedSerializerOptions={"sortCollections"},
noInherit={"allowedSerializerOptions"}
)
public MyBean get() { ... }
}

BasicUniversalConfig​

Resources using BasicUniversalConfig have a comprehensive default allowlist that covers the most common and safe session properties for all supported serializers and parsers.

Client Usage​

Juneau REST Client (classic)​

The RestClient (classic) and RestRequest (classic) APIs provide dedicated methods for setting session options. These convenience methods live on the classic REST client stack (org.apache.juneau.rest.client.classic) only — the default next-generation RestClient does not have them.

RestClient client = RestClient.create()
.rootUrl("http://localhost:8080/myresource")
.build();

Via HTTP Headers (JSON5 format)​

// Builder-level (applies to all requests)
RestClient client = RestClient.create()
.rootUrl("http://localhost:8080/myresource")
.serializerSessionOptionsHeader("{useWhitespace:true,addBeanTypes:false}")
.build();

// Request-level
client.get("/mybean")
.serializerSessionOptionsHeader("{useWhitespace:true}")
.run()
.getContent().as(MyBean.class);

// Map form (serialized as JSON5)
client.get("/mybean")
.serializerSessionOptionsHeader(Map.of("useWhitespace", true))
.run()
.getContent().as(MyBean.class);

Via Query Parameters (UON format)​

// Builder-level (applies to all requests via default query params)
RestClient client = RestClient.create()
.rootUrl("http://localhost:8080/myresource")
.serializerSessionOptionsQueryDefault("(useWhitespace=true)")
.build();

// Request-level
client.get("/mybean")
.serializerSessionOptionsQuery("(useWhitespace=true)")
.run()
.getContent().as(MyBean.class);

Parser Options​

// Parser options work the same way
client.post("/mybean", body)
.parserSessionOptionsHeader("{trimStrings:true}")
.run();

Raw HTTP​

Without the Juneau client, you can send options via raw HTTP:

Header format (JSON5/JSON map):

X-Juneau-Serializer-Options: {useWhitespace:true,addBeanTypes:false}
X-Juneau-Parser-Options: {trimStrings:true}

Query parameter format (UON map):

GET /myresource/mybean?juneauSerializerOptions=(useWhitespace=true)

Programmatic Override​

Server-side code can also set session properties programmatically via RestRequest:

@RestGet
public MyBean get(RestRequest req) {
// These are applied regardless of allowedSerializerOptions
req.setSerializerSessionProperty("addBeanTypes", true);
req.setSerializerSessionProperty("maxIndent", 2);
return myBean;
}

Programmatic values and HTTP-provided values are merged, with programmatic values taking precedence.

Safe Properties​

Not all session properties are safe to expose via HTTP. Properties that control internal server behavior (like javaMethod, resolver, schema, outer) should never be in the allowlist.

Safe properties to expose include formatting and output control properties:

PropertyApplies ToDescription
useWhitespaceWritersEnable whitespace in output
maxIndentWritersMaximum indentation level
quoteCharWritersQuote character for strings
keepNullPropertiesSerializersInclude null-valued properties
trimStringsSerializers/ParsersTrim string values
addBeanTypesSerializersAdd _type annotations
addRootTypeSerializersAdd root type annotation
sortCollectionsSerializersSort collections before serializing
sortMapsSerializersSort maps before serializing
trimEmptyCollectionsSerializersRemove empty collections
trimEmptyMapsSerializersRemove empty maps
binaryFormatBinary serializersBinary encoding format (BASE64, HEX, etc.)
escapeSolidusJSONEscape forward slashes (/)
encodingUONURL-encode special characters
validateEndJSON/UON parsersValidate end of input
expandedParamsURL-encoding parserUse expanded parameter format
preserveRootElementXML parserPreserve root XML element

Security Considerations​

  • Only add properties to the allowlist that clients should be permitted to change.
  • Properties controlling server internals (e.g., javaMethod, schema) must never be exposed.
  • The allowlist is enforced on the server; clients cannot override the enforcement.
  • If a client sends a disallowed property, the server returns a 400 Bad Request.