Class WidgetsMixin.WidgetValidationProcessor
- All Implemented Interfaces:
ResponseProcessor
- Enclosing class:
- WidgetsMixin
Widget.validate() gate: fail-closed structural validation for any
REST response content that is a Widget, giving the JSON serving path the same gate the
juneau-console-views HTML emitters already give every Widget they consume.
Why this is a ResponseProcessor, not a RestContext hook
juneau-rest-server does not (and must not) depend on this module, so a hard-coded validation step
inside it cannot see Widget without inverting that dependency. A ResponseProcessor declared
here, discovered by every classpath that carries this module via ServiceLoader, needs no such
reflection or hoisted marker interface — see the class Javadoc.
Why NEXT, never FINISHED
This processor validates and declines to handle: it never claims the response, so it cannot perturb chain
ordering, content-type negotiation, or the NotImplemented fallthrough. Non-Widget content
(including the unrelated examples.views.Widget demo row bean and the legacy
org.apache.juneau.rest.server.widget.Widget SVL resolver — see the module Javadoc's naming
collision note) costs one instanceof test and is otherwise untouched.
Why InternalServerError (500), not the caller's problem
A malformed Widget reaching the serving path is a server defect — the client asked for
a dialog correctly and the server built a broken one — not an inbound-validation failure of the kind
ValidationException (400) is scoped to. The underlying IllegalArgumentException rides as the
cause so the message names the failing rule.
Deliberately not deduplicated against ModalDef.checked()/FormDef.checked()
A widget that already called checked() is validated twice per response: once at build time, once
here. No validated flag is added to skip the second pass — a mutable "already validated" flag
on a wire bean would re-introduce an order-dependence bug in the validation dimension (mutate-after-checked)
that this module's contract deliberately avoids elsewhere. validate() is cheap and idempotent, so the
repeat costs nothing worth building around.
Traversal is top-level only
Only res.getContent() itself is tested. Nested widgets are covered by the beans' own recursive
validate() (e.g. ModalDef.validate() → FormDef.validate()); a Widget
inside a Collection/Map envelope is not walked into — no endpoint in this tree returns
that shape, and walking one would collide with the unrelated examples.views.Widget row-bean lists
some example endpoints do return.
Escape hatch
A resource that must serve a deliberately-invalid Widget can override the response-processor chain
entirely with a @Bean ResponseProcessorList factory method, which replaces the whole list. There is
no narrower, dedicated opt-out.
- Since:
- 10.0.0
-
Field Summary
Fields inherited from interface org.apache.juneau.rest.server.processor.ResponseProcessor
FINISHED, NEXT, RESTART -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionintprocess(RestOpSession opSession) Process this response if possible.
-
Constructor Details
-
WidgetValidationProcessor
public WidgetValidationProcessor()
-
-
Method Details
-
process
Description copied from interface:ResponseProcessorProcess this response if possible.- Specified by:
processin interfaceResponseProcessor- Parameters:
opSession- The HTTP call.- Returns:
- One of the following codes:
0 - The processor could not handle the request.1 - The processor was able to fully handle the request.2 - The processor was able to partially handle the request by replacing the output. The response processors should start over.
-