* WW-5626 spike: validate Jackson per-property authorization mechanism Validates that the Approach C design is feasible before committing to a detailed implementation plan. Wraps each SettableBeanProperty via BeanDeserializerModifier; intercepts deserializeAndSet to authorize against a path built from a ThreadLocal Deque; uses skipChildren() to discard unauthorized values; uses [0] suffix for collection/map/array elements to match ParametersInterceptor depth semantics. Findings: - Delegating base class via 'protected delegate' field is the right pattern - addOrReplaceProperty(prop, true) is the correct builder API - Reject-at-parent skips all nested deserialization (better security than two-phase copy: setter side effects on unauthorized properties never fire) - JavaType#isCollectionLikeType/isMapLikeType/isArrayType detects the indexed-path case Spike is kept under .../spike/ as a learning artifact; it will be replaced by production code + tests in subsequent commits. * WW-5626 add ParameterAuthorizationContext for deserializer-level authorization Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * WW-5626 address review feedback on ParameterAuthorizationContext Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * WW-5626 add AuthorizationAwareContentTypeHandler marker interface * WW-5626 add AuthorizingSettableBeanProperty for Jackson per-property authorization * WW-5626 add ParameterAuthorizingModule installing the property wrapper on Jackson mappers * WW-5626 register ParameterAuthorizingModule on default Jackson REST handlers * WW-5626 use AuthorizationAwareContentTypeHandler path when handler supports it * WW-5626 add integration tests proving the new Jackson authorization path is used * WW-5626 deprecate XStreamHandler in favor of JacksonXmlHandler * WW-5626 remove Jackson auth spike; replaced by production tests * WW-5626 make JuneauXmlHandler authorization-aware via post-parse walk Implements AuthorizationAwareContentTypeHandler. When ParameterAuthorizationContext is active (set by ContentTypeInterceptor when requireAnnotations=true), the handler walks the parsed result tree and copies only authorized properties to the target, descending into nested beans/collections/maps/arrays with indexed-path semantics ([0] suffix) for parity with ParametersInterceptor. Note: Juneau parses the entire result tree before our walk runs, so setter side effects on transient nested objects can fire even for unauthorized properties — those transient objects are then discarded. This is functionally equivalent to the legacy two-phase copy in ContentTypeInterceptor; only the Jackson handlers achieve the stronger guarantee where unauthorized subtrees are never instantiated at all (they use Jackson's BeanDeserializerModifier + skipChildren). When no context is bound (default config), behavior is unchanged: parser.parse + BeanUtils.copyProperties. * WW-5626 add JuneauXmlHandler integration tests for @StrutsParameter authorization * WW-5626 test(rest): cover JuneauXmlHandler post-parse walk for collections, maps, arrays Sonar reported 51 uncovered new lines in JuneauXmlHandler (48.8% coverage on the post-parse authorization walk — the security-critical code path the branch exists to introduce). Add integration coverage for the previously-uncovered branches: - collection-of-scalars (List<String> tags) - collection-of-beans (List<Address> addresses) - map-of-scalars (Map<String,String> attributes) - array-of-scalars (String[] aliases) - empty collection - malformed XML wrapped as IOException Also drop two unnecessary casts (Sonar S1905) on lines 243/252 — the unchecked conversion happens at the return statement, the explicit casts were redundant under the existing @SuppressWarnings("unchecked"). Add @Override on the inline AnyConstraintMatcher.matches override (Sonar S1161). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * WW-5626 test(rest): cover AuthorizingSettableBeanProperty builder-path deserialization Sonar reported 11 uncovered new lines on AuthorizingSettableBeanProperty (66.7% coverage). All 11 are in deserializeSetAndReturn — the alternate Jackson entry point used for builder-pattern deserialization, never triggered by setter-based fixtures like Person. Add an @JsonDeserialize(builder=...) fixture (ImmutablePerson) that forces Jackson to use BuilderBasedDeserializer, which dispatches property writes through deserializeSetAndReturn. Three new tests exercise the path: inactive-context pass-through, top-level authorization, and full rejection. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * WW-5626 refactor(rest): extract helpers from ContentTypeInterceptor.intercept Sonar S3776 flagged intercept() at cognitive complexity 16 (limit 15). Extract the body-handling branches into named helpers: - openBodyReader: encoding-aware reader from the request InputStream - applyRequestBody: dispatcher between requireAnnotations on/off paths - applyWithAuthorizationContext: bind + delegate + unbind for AuthorizationAware handlers - applyTwoPhaseDeserialize: legacy fresh-instance + copyAuthorizedProperties path intercept() drops to ~12 lines and reads as a flat sequence: resolve target, delegate body application, invoke. Each helper carries the comment that explains the security model for its branch. Add @Override on the inline AnyConstraintMatcher.matches override (Sonar S1161). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
The Apache Struts web framework
The Apache Struts web framework is a free open-source solution for creating Java web applications.
Documentation
More information can be found on the homepage. Please read the Security Guide, and the JavaDocs can be browsed. Questions related to the usage of Apache Struts should be posted to the user mailing list.
Description
Web applications differ from conventional websites in that web applications can create a dynamic response. Many websites deliver only static pages. A web application can interact with databases and business logic engines to customize a response.
Web applications based on JavaServer Pages sometimes commingle database code, page design code, and control flow code. In practice, we find that unless these concerns are separated, larger applications become difficult to maintain.
One way to separate concerns in a software application is to use a Model-View-Controller (MVC) architecture. The Model represents the business or database code, the View represents the page design code, and the Controller represents the navigational code. The Struts framework is designed to help developers create web applications that utilize an MVC architecture.
The framework provides three key components:
- A “request” handler provided by the application developer that is mapped to a standard URI.
- A “response” handler that transfers control to another resource which completes the response.
- A tag library that helps developers create interactive form-based applications with server pages.
The framework’s architecture and tags are buzzword compliant. Struts works well with conventional REST applications and with technologies like SOAP and AJAX.
The Apache Struts Project
The Apache Struts Project is the open source community that creates and maintains the Apache Struts framework. The project consists of a diverse group of volunteers who share common values regarding collaborative, community-based open source development. The Apache Struts Project is proud to share these values with our parent organization: The Apache Software Foundation.
The project is called “Struts” because the framework is meant to furnish the “invisible underpinnings” that support professional application development. Struts provides the glue that joins the various elements of the standard Java platform into a coherent whole. Our goal is to leverage existing standards by producing the missing pieces we need to create enterprise-grade applications that are easy to maintain over time.
The Apache Struts Project offered two major versions of the Struts framework. Currently we are only maintaining the Struts 2 version. It is recommended to upgrade all Struts 1.x applications to Struts 2. Please do not start new application development using Struts 1.x, as we are no longer issuing security patches.
Struts 2 was originally known as WebWork 2. After working independently for several years, the WebWork and Struts communities joined forces to create Struts 2. The 2.x framework is the best choice for teams who value elegant solutions to difficult problems.
Why should you use Apache Struts?
Apache Struts is a modern, maintained and full-featured web framework. As it has been around for years and grown a huge user base it is unlikely it will go away anytime soon. Not only that, we have dedicated users and developers on the project. Apache Struts is licensed under the Apache License 2.0 and this will not change. We maintain a clean IP and you are “safe” to use the project. Sometimes you are not “safe” to use a project when a company controls the SCM. Access to Source Code doesn’t mean it is free. With Apache Struts, you are not only free to “do what you want with it”, you can even contribute (which is not always the case). And best of all: you can become a part of the core team too.
It is usually very easy to integrate other technologies with Apache Struts. If you are using an ORM like Apache Cayenne, Hibernate or JDBC, you will not have any restrictions. Apache Struts is not even tied too much to a frontend technology. In old days it was JSP, then came Velocity and Freemarker. Nowadays you might build your web application with just static HTML and AngularJS. Or you might want to use Sitemesh or Tiles. This all is no problem due to Struts' elegant and easy-to-use extension mechanisms.
Unlike other, component-oriented frameworks, we do not aim to hide the stateless nature of the web. We think it is perfectly acceptable to build upon a Request/Response cycle. We also think the MVC pattern is not so bad, just because it is old. In fact, we believe the Apache Struts architecture is clean and easy to understand.
Of course, if you wish to build components on the server side which render on the front end side, you will most likely not want Struts. This is a different approach which promises to reduce the amount of HTML/JavaScript knowledge needed and to create reusable components for the view layer. Projects like Wicket and Tapestry serve this purpose very well. As with every framework, you need to decide if it makes sense for you to build components or if you prefer the Struts approach.
Commercial Support
The Apache Struts community does not offer commercial support by itself, but we maintain a list of companies offering commercial support on our website.
Some Apache Struts maintainers are working with Tidelift to provide commercial support and invest paid working time in the improvement of the Apache Struts framework. For more information, visit the Tidelift resources regarding Apache Struts
Thank you
YourKit is kindly supporting open source projects with its full-featured Java Profiler. YourKit is the creator of innovative and intelligent tools for profiling Java and .NET applications. As an Apache committer, you can get a free license at YourKit's open source sponsorship program.