Lukasz Lenart created WW-5748:
---------------------------------

             Summary: Registering ParameterAuthorizingModule breaks unwrapped 
XML lists in JacksonXmlHandler
                 Key: WW-5748
                 URL: https://issues.apache.org/jira/browse/WW-5748
             Project: Struts 2
          Issue Type: Bug
          Components: Plugin - REST
            Reporter: Lukasz Lenart


h2. Summary

{{JacksonXmlHandler}} registers {{ParameterAuthorizingModule}} on its 
{{XmlMapper}}. {{ObjectMapper.registerModule}} inserts a module's 
{{BeanDeserializerModifier}} at the _head_ of the modifier list, so the Struts 
modifier runs before Jackson XML's own {{XmlBeanDeserializerModifier}}. The 
Struts modifier wraps every bean deserializer in {{RedactionAwareDeserializer}} 
(a {{DelegatingDeserializer}}); the XML modifier then tests the deserializer it 
receives with {{instanceof BeanDeserializerBase}}, does not recognise the 
wrapper, and skips installing its {{WrapperHandlingDeserializer}}. 
Unwrapped-list handling is therefore lost for every bean read through the XML 
handler.

h2. Current behaviour

Reproduced with a plain {{XmlMapper}} (no authorization context bound — the 
module's mere registration is enough):

{code:java}public class Bean {
    @JacksonXmlElementWrapper(useWrapping = false)
    public List<String> items;
    public String name;
}
{code}

{code:xml}<Bean><items>a</items><items>b</items><name>n</name></Bean>
{code}

Without the module: {{items = [a, b]}}, {{name = n}}. With the module 
registered: {{MismatchedInputException: Cannot construct instance of 
java.util.ArrayList ... no String-argument constructor/factory method to 
deserialize from String value ('a')}}. {{@JacksonXmlText}} is unaffected 
(verified).

Present since the module was introduced (7.2.0); independent of 
{{struts.parameters.requireAnnotations}}.

h2. Proposed change

Let the XML module's modifier see a {{BeanDeserializerBase}}. Options, in order 
of preference:
* in {{ParameterAuthorizingModule.setupModule}}, or in {{JacksonXmlHandler}}, 
register the modifier so that it runs _after_ the format module's (e.g. 
construct the handler's mapper with the XML module first and add the Struts 
modifier through {{SimpleModule.setDeserializerModifier}} on a module 
registered last — verify the resulting order, since {{insertInListNoDup}} 
prepends);
* or have {{RedactionAwareDeserializer}} be applied from a later hook than 
{{modifyDeserializer}}.

Add a test on {{JacksonXmlHandler}} with an unwrapped list, with and without an 
authorization context.

h2. Compatibility notes

No configuration or API change; only restores documented Jackson XML behaviour 
for the REST plugin's XML handler.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to