Skip to content

Navigation Menu

Sign in
Sign up

Understanding AtmosphereInterceptor

jfarcand edited this page Feb 18, 2026 · 18 revisions

Understanding AtmosphereInterceptor

Advanced topic. Interceptors let you customize the request/response pipeline. Most applications don't need custom interceptors — @ManagedService installs the necessary ones automatically.

An AtmosphereInterceptor sits in the processing chain between the client and your handler. It can inspect, modify, or reject requests and responses.

Built-in Interceptors

These are installed automatically by @ManagedService:

Interceptor Purpose
AtmosphereResourceLifecycleInterceptor Auto-suspends connections based on transport
TrackMessageSizeInterceptor Prepends message length for guaranteed delivery
HeartbeatInterceptor Sends periodic heartbeats to keep connections alive
SuspendTrackerInterceptor Tracks suspended resources for cleanup
ManagedServiceInterceptor Routes messages to @Message annotated methods

Other useful interceptors:

Interceptor Purpose
MDCInterceptor Populates SLF4J MDC with atmosphere.uuid, atmosphere.transport, atmosphere.broadcaster for structured logging
RoomProtocolInterceptor Bridges atmosphere.js room protocol to server-side Rooms
RoomInterceptor Auto-joins resources to rooms based on URL path
BroadcastOnPostAtmosphereInterceptor Auto-broadcasts POST body to the Broadcaster
CorsInterceptor Adds CORS headers

MDCInterceptor — Structured Logging

MDCInterceptor sets SLF4J MDC keys on every request so log lines include Atmosphere context:

MDC key Value
atmosphere.uuid The unique resource identifier
atmosphere.transport Transport type (websocket, long-polling, sse, etc.)
atmosphere.broadcaster Broadcaster ID the resource is attached to

Logback pattern example:

%d{HH:mm:ss.SSS} [%thread] %-5level [uuid=%X{atmosphere.uuid} transport=%X{atmosphere.transport}] %logger{36} - %msg%n

MDC keys are automatically included as top-level fields in JSON layouts (logstash-logback-encoder, logback-contrib).

Writing a Custom Interceptor

public class LoggingInterceptor extends AtmosphereInterceptorAdapter {
 @Override
 public Action inspect(AtmosphereResource r) {
 // Called before the handler
 log.info("Request from {} via {}", r.uuid(), r.transport());
 return Action.CONTINUE; // Proceed to next interceptor/handler
 // return Action.CANCELLED; // Stop processing (e.g., reject request)
 // return Action.SUSPEND; // Suspend the connection
 }
 @Override
 public void postInspect(AtmosphereResource r) {
 // Called after the handler
 }
 @Override
 public void configure(AtmosphereConfig config) {
 // Called once at startup
 }
}

Registering Interceptors

Via @ManagedService

@ManagedService(path = "/chat",
 interceptors = {LoggingInterceptor.class, RateLimitInterceptor.class})
public class Chat { /* ... */ }

These are appended to the default set — they don't replace it.

Via Annotation

@AtmosphereInterceptorService
public class LoggingInterceptor extends AtmosphereInterceptorAdapter {
 // Auto-registered when annotation scanning is enabled
}

Programmatically

framework.interceptor(new LoggingInterceptor());

Interceptor Priority

Control execution order with PRIORITY:

public class EarlyInterceptor extends AtmosphereInterceptorAdapter {
 @Override
 public PRIORITY priority() {
 return InvokationOrder.BEFORE_DEFAULT; // Run before defaults
 // InvokationOrder.AFTER_DEFAULT // Run after defaults (default)
 // InvokationOrder.FIRST_BEFORE_DEFAULT // Run first, before everything
 }
}

Clone this wiki locally

AltStyle によって変換されたページ (->オリジナル) /