0

Struts version: 2.5.30

Struts Spring Configuration:

    <constant name="struts.objectFactory" value="spring" />
    <!-- spring injection wont auto happen.  Need to annotate with @autowired -->
    <constant name="struts.objectFactory.spring.autoWire" value="no" />

Action Mapping:

        <action name="loginAuthentication" class="com.webexchange.actions.security.Login" method="executeNoSecurity">
            <interceptor-ref name="token" />
            <interceptor-ref name="stackWithSecurity" />

            <result name="success" type="redirectAction">
                <param name="actionName">${forwardUrl}</param>
                <param name="namespace">${forwardNamespace}</param>
                <param name="struts.token.name">token</param>
                <param name="token">${token}</param>
            </result>
            <result name="input">/Login.jsp</result>
            <result name="invalid.token">/WEB-INF/jsp/centers/common/SystemActionErrors.jsp</result>
        </action>

String spring bean introduced which is causing this behavior to occur

    @Bean("passwordRuleString")
    public String passwordRuleString(@Autowired @Qualifier("passwordRuleList") List<String> passwordRuleList) {

       StringBuilder sb = new StringBuilder();

        sb.append("Password must be ");

        boolean comma = false;

        for (String s : passwordRuleList){
            if(comma) {
                sb.append(", ");
            }
            sb.append(s);
            comma = true;
        }

        return sb.toString();
    }
}

Based on the result type, struts runs the following constructor org.apache.struts2.result.ServletActionRedirectResult#ServletActionRedirectResult(java.lang.String, java.lang.String, java.lang.String, java.lang.String)

Intellij ServletActionRedirectResult debug

All the the parameter strings have been injected with the String spring bean instance. However, I do have the struts.objectFactory.spring.autoWire setting set to "no". This is defined as "Turn off externally defined autowiring. Annotation-driven injection and injection based on Springs *Aware-interfaces still applies" in the documentation. https://struts.apache.org/plugins/spring/

Most of these get overwritten after the constructor is called, however, the methodName value remains and causes the redirect to append it to my url

/myNamespace/myAction.action!Password must be Min length of 5, Contain at least 1 Number, Contain at least 1 Letter

instead of the expected

/myNamespace/myAction.action

The issue ends up creating a 404 result in my application.

Is there a configuration setting to stop Struts from internally autowiring by type, is this a bug, or do I need to only create spring beans with my own classes when using with Struts?

Paul Zepernick
  • 1,452
  • 1
  • 11
  • 25
  • is that by design or a struts bug? – Paul Zepernick Nov 15 '22 at 17:03
  • 1
    Let's say: it's a spring feature! – xerx593 Nov 15 '22 at 17:04
  • Obviously, you can't turn off the feature, for more detailed explanation of the plugin see [this](https://stackoverflow.com/a/28477395/573032) answer. – Roman C Nov 17 '22 at 08:21
  • I'm not sure that this is really a duplicate question, and wanted to add more context. This is not related to how struts is autowiring into my action class, but the fact that struts is using spring to autowire (by type) it's own internal classes. ServletActionRedirectResult class is a struts class which is getting my "String" spring bean injected into it. I have configured to not autowire by type, however, this is not honored by the struts internal classes and only applies to action classes. Avoid creating java.util.* spring beans when using the struts-spring plugin is the bottom line. – Paul Zepernick Nov 21 '22 at 15:12

0 Answers0