Skip to content

Conversation

@lukaszlenart
Copy link
Member

@lukaszlenart lukaszlenart commented Nov 16, 2025

Summary

Implements dynamic parameter evaluation for file upload validation in ActionFileUploadInterceptor by adding support for the WithLazyParams interface. This enables runtime evaluation of ${...} expressions for validation rules, allowing file upload constraints to be determined dynamically based on action properties, session data, or other runtime values.

Closes WW-5585

Changes

Core Implementation

  • ActionFileUploadInterceptor: Added implements WithLazyParams to enable lazy parameter injection
  • Comprehensive JavaDoc: Documented both static and dynamic configuration approaches with examples
  • No breaking changes: Existing static configurations continue to work unchanged

Testing

  • Added 7 new unit tests for dynamic parameter evaluation scenarios:
    • Dynamic parameter evaluation with ValueStack
    • Per-request parameter changes
    • Dynamic file extension validation
    • Dynamic file size validation
    • Dynamic security validation
    • Dynamic wildcard extension matching
    • Interface implementation verification
  • All 23 tests pass successfully (16 existing + 7 new)

Showcase Example

  • DynamicFileUploadAction: Demonstrates runtime configuration with two upload modes
    • Document mode: PDF/Word files, 5MB limit
    • Image mode: JPEG/PNG files, 2MB limit
  • JSP pages: Upload form and success page showing dynamic validation rules
  • Configuration: Uses ${uploadConfig.*} expressions in struts-fileupload.xml

Technical Details

The implementation leverages Struts' existing WithLazyParams marker interface and LazyParamInjector framework:

  1. Action's prepare() method sets up configuration based on user input
  2. Framework evaluates ${...} expressions against ValueStack at runtime
  3. Interceptor receives evaluated parameters before file processing
  4. Validation rules apply dynamically per request

Example Configuration

<action name="doDynamicUpload" class="org.apache.struts2.showcase.fileupload.DynamicFileUploadAction" method="upload">
    <interceptor-ref name="defaultStack">
        <param name="actionFileUpload.allowedTypes">${uploadConfig.allowedMimeTypes}</param>
        <param name="actionFileUpload.allowedExtensions">${uploadConfig.allowedExtensions}</param>
        <param name="actionFileUpload.maximumSize">${uploadConfig.maxFileSize}</param>
    </interceptor-ref>
    <result name="input">/WEB-INF/fileupload/dynamic-upload.jsp</result>
    <result>/WEB-INF/fileupload/dynamic-upload-success.jsp</result>
</action>

Benefits

  • Zero breaking changes for existing configurations
  • Minimal code change (single interface addition)
  • Maintains all existing security features
  • Enables dynamic validation rules based on runtime context
  • Comprehensive test coverage for new functionality

Test Plan

  • All existing tests pass
  • New tests verify dynamic parameter evaluation
  • Showcase example demonstrates practical usage
  • No regression in static configuration behavior

🤖 Generated with Claude Code

@lukaszlenart lukaszlenart force-pushed the feature/WW-5585-dynamic-file-upload-params branch from 32557d8 to cf84e2e Compare November 17, 2025 14:26
lukaszlenart and others added 6 commits November 21, 2025 08:55
…oad validation

- Add WithLazyParams interface to ActionFileUploadInterceptor
- Enable runtime evaluation of ${...} expressions for validation rules
- Add comprehensive JavaDoc with static and dynamic examples
- Add 7 new unit tests for dynamic parameter scenarios
- Create DynamicFileUploadAction showcase with document/image modes
- All 23 tests pass successfully

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Mark uploadConfig field as transient for serialization compliance
- Add @OverRide annotation to input() method
- Add DOCTYPE html declarations to JSP files
- Add lang="en" attributes to html elements for accessibility
- Fix minor code formatting issues

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add DynamicFileUploadTest with 7 comprehensive test cases
- Test valid document and image uploads
- Test file type validation (documents reject images, images reject documents)
- Test size limit validation (5MB for documents, 2MB for images)
- Test switching between upload modes
- Add helper methods for creating test files of various sizes
- Follow existing FileUploadTest patterns using HtmlUnit

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…terceptors

Read uploadType directly from request in prepareUpload() method to ensure
upload validation config is set before WithLazyParams interceptor evaluates
the OGNL expressions. This fixes dynamic file type validation not working.

Also fixes:
- Test file creation using correct File.createTempFile prefix pattern
- Default port changed to 8090 in test utils
- Increased struts.multipart.maxSize for testing
- maximumSize parameter changed to String to support OGNL expressions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Change maximumSize field type from String to Long for type safety
- Remove NumberUtils dependency and parsing logic
- Remove unused isNonEmpty() method
- Modernize instanceof patterns using Java 16+ pattern matching
- Fix error message key for null content validation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Documents investigation into dynamic file upload limits at parsing time.
Conclusion: current approach with global hard limits + WithLazyParams
interceptor validation is sufficient.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@lukaszlenart lukaszlenart force-pushed the feature/WW-5585-dynamic-file-upload-params branch from c768957 to b620ee9 Compare November 21, 2025 07:55
@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
20.2% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@lukaszlenart lukaszlenart marked this pull request as ready for review November 21, 2025 08:05
@lukaszlenart lukaszlenart merged commit 939576c into main Nov 22, 2025
9 of 10 checks passed
@lukaszlenart lukaszlenart deleted the feature/WW-5585-dynamic-file-upload-params branch November 22, 2025 14:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants