This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch docs
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/docs by this push:
     new 2a78845917 Add Session Options via HTTP documentation
2a78845917 is described below

commit 2a78845917a9f2a6f987c98eafcb8281285a8ebc
Author: James Bognar <[email protected]>
AuthorDate: Sat Apr 4 14:58:30 2026 -0400

    Add Session Options via HTTP documentation
    
    - New 10.21a.SessionOptions.md covering HTTP-based session property override
    - Updated 02.03.SerializersAndParsers.md with REST integration and HTTP 
options section
    - Updated 12.02.PojoMarshalling.md with client-side session options API 
examples
    
    Made-with: Cursor
---
 pages/topics/02.03.SerializersAndParsers.md |  40 +++++-
 pages/topics/10.21a.SessionOptions.md       | 184 ++++++++++++++++++++++++++++
 pages/topics/12.02.PojoMarshalling.md       |  30 +++++
 3 files changed, 253 insertions(+), 1 deletion(-)

diff --git a/pages/topics/02.03.SerializersAndParsers.md 
b/pages/topics/02.03.SerializersAndParsers.md
index 977797ecea..c1a7df4445 100644
--- a/pages/topics/02.03.SerializersAndParsers.md
+++ b/pages/topics/02.03.SerializersAndParsers.md
@@ -375,4 +375,42 @@ public void put(RestRequest req, @Body MyBean body) {
     req.setParserSessionProperty("trimStrings", true);
     // body is then parsed with trimStrings=true
 }
-```
\ No newline at end of file
+```
+
+#### HTTP-Based Session Options
+
+Clients can also pass session properties via HTTP headers or query parameters 
when the server has enabled them. The server controls which properties are 
allowed using `@Rest(allowedSerializerOptions, allowedParserOptions)` or 
`@RestOp(allowedSerializerOptions, allowedParserOptions)`:
+
+```java
+// Allow clients to override these specific serializer properties
+@Rest(
+    allowedSerializerOptions={"useWhitespace", "addBeanTypes"},
+    allowedParserOptions={"trimStrings"}
+)
+public class MyResource extends BasicRestServlet {
+    ...
+}
+```
+
+Clients send options using the `X-Juneau-Serializer-Options` header (JSON5 
format) or `juneauSerializerOptions` query parameter (UON format):
+
+```java
+// Client using Juneau REST client
+RestClient client = RestClient.create()
+    .rootUrl("http://localhost:8080/myresource";)
+    .build();
+
+// Via header (JSON5 format)
+client.get("/mybean")
+    .serializerSessionOptionsHeader("{useWhitespace:true,addBeanTypes:false}")
+    .run()
+    .getContent().as(MyBean.class);
+
+// Via query parameter (UON format)
+client.get("/mybean")
+    .serializerSessionOptionsQuery("(useWhitespace=true)")
+    .run()
+    .getContent().as(MyBean.class);
+```
+
+See [Session Options via HTTP](SessionOptions) for complete documentation.
\ No newline at end of file
diff --git a/pages/topics/10.21a.SessionOptions.md 
b/pages/topics/10.21a.SessionOptions.md
new file mode 100644
index 0000000000..201b380ca0
--- /dev/null
+++ b/pages/topics/10.21a.SessionOptions.md
@@ -0,0 +1,184 @@
+---
+title: "Session Options via HTTP"
+slug: SessionOptions
+---
+
+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)
+
+```java
+@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)
+
+```java
+@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:
+
+```java
+@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
+
+The `RestClient` and `RestRequest` APIs provide dedicated methods for setting 
session options:
+
+```java
+RestClient client = RestClient.create()
+    .rootUrl("http://localhost:8080/myresource";)
+    .build();
+```
+
+#### Via HTTP Headers (JSON5 format)
+
+```java
+// 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)
+
+```java
+// 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
+
+```java
+// 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`:
+
+```java
+@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:
+
+| Property | Applies To | Description |
+|---|---|---|
+| `useWhitespace` | Writers | Enable whitespace in output |
+| `maxIndent` | Writers | Maximum indentation level |
+| `quoteChar` | Writers | Quote character for strings |
+| `keepNullProperties` | Serializers | Include null-valued properties |
+| `trimStrings` | Serializers/Parsers | Trim string values |
+| `addBeanTypes` | Serializers | Add `_type` annotations |
+| `addRootType` | Serializers | Add root type annotation |
+| `sortCollections` | Serializers | Sort collections before serializing |
+| `sortMaps` | Serializers | Sort maps before serializing |
+| `trimEmptyCollections` | Serializers | Remove empty collections |
+| `trimEmptyMaps` | Serializers | Remove empty maps |
+| `binaryFormat` | Binary serializers | Binary encoding format (`BASE64`, 
`HEX`, etc.) |
+| `escapeSolidus` | JSON | Escape forward slashes (`/`) |
+| `encoding` | UON | URL-encode special characters |
+| `validateEnd` | JSON/UON parsers | Validate end of input |
+| `expandedParams` | URL-encoding parser | Use expanded parameter format |
+| `preserveRootElement` | XML parser | Preserve 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`.
diff --git a/pages/topics/12.02.PojoMarshalling.md 
b/pages/topics/12.02.PojoMarshalling.md
index b4f5847cd9..ebdc8e731b 100644
--- a/pages/topics/12.02.PojoMarshalling.md
+++ b/pages/topics/12.02.PojoMarshalling.md
@@ -97,3 +97,33 @@ These can be overridden using the following methods:
 <node-1><java-method><a 
href="/site/apidocs/org/apache/juneau/rest/client/RestClient.Builder.html#partSerializer(java.lang.Class)"
 target="_blank">partSerializer(Class&lt;? extends 
HttpPartSerializer&gt;)</a></java-method></node-1>
 <node-1><java-method><a 
href="/site/apidocs/org/apache/juneau/rest/client/RestClient.Builder.html#partParser(java.lang.Class)"
 target="_blank">partParser(Class&lt;? extends 
HttpPartParser&gt;)</a></java-method></node-1>
 </tree>
+
+## Session Options via HTTP
+
+The Juneau REST client supports sending serializer and parser session 
properties via HTTP headers or query parameters. This allows controlling 
per-request marshalling behavior when the server has enabled it:
+
+```java
+RestClient client = RestClient.create()
+    .rootUrl("http://localhost:8080/myapi";)
+    .build();
+
+// Send serializer options via header (JSON5 format)
+client.get("/mybean")
+    .serializerSessionOptionsHeader("{useWhitespace:true}")
+    .run()
+    .getContent().as(MyBean.class);
+
+// Send parser options via query parameter (UON format)
+client.post("/mybean", body)
+    .parserSessionOptionsQuery("(trimStrings=true)")
+    .run();
+
+// Set default options for all requests via builder
+RestClient clientWithDefaults = RestClient.create()
+    .rootUrl("http://localhost:8080/myapi";)
+    .serializerSessionOptionsHeader("{addBeanTypes:false}")
+    .parserSessionOptionsQueryDefault("(trimStrings=true)")
+    .build();
+```
+
+See [Session Options via HTTP](SessionOptions) for complete documentation on 
server configuration and security.

Reply via email to