Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
2.3-next-M3, 2.3-next-M4, 4.0.0-RC1
-
None
Description
Hello,
could you please check FacesConfigUnmarshallerImpl, we discovered some issues in navigation rules parsing, especially view-param / redirect-param. Is there is something wrong on our side?
The specific configuration of navigation rules xml looks like this
<redirect> <view-param> <name>cid</name> <value></value> </view-param> </redirect>
Issue 1. - viewParams are not handled correctly:
onChild("view-param", n, (cn) -> { ViewParamImpl vp = new ViewParamImpl(); r.addViewParam(vp); onChild("name", cn, (ccn) -> { vp.setName(ccn.getTextContent()); }); onChild("value", cn, (ccn) -> { vp.setValue(ccn.getTextContent()); }); });
If I understand it correctly, empty ViewParamImpl si created, added to r (RedirectImpl), and after that it is filled with xml values.
In RedirectImpl, method addViewParam, is ViewParam attribute transformed to key/value combination and added to local HashMap. Because it is empty (yet), empty key is created in local HashMap, and no values are filled.
public void addViewParam(ViewParamImpl viewParam) { if (viewParams == null) { viewParams = new HashMap<>(3, 1f); } List<String> params = viewParams.computeIfAbsent(viewParam.getName(), k -> new ArrayList<>(3)); params.add(viewParam.getValue()); }
Rest of implementation is irrelevant.
What do you think about changing order of command like that ->
onChild("view-param", n, (cn) -> { ViewParamImpl vp = new ViewParamImpl(); onChild("name", cn, (ccn) -> { vp.setName(ccn.getTextContent()); }); onChild("value", cn, (ccn) -> { vp.setValue(ccn.getTextContent()); }); r.addViewParam(vp); // moved down });
same, with redirect-param .. and maybe others ..
Issue 2. - empty value in view-param parameter
As is seen in example above, we need to pass empty value to view-param. But method getTextContent returns null as a value.
After that, NPE is throwed:
java.lang.NullPointerException: null at java.net.URLEncoder.encode(URLEncoder.java:204) at org.apache.myfaces.context.servlet.ServletExternalContextImpl.encodeURL(ServletExternalContextImpl.java:990) at org.apache.myfaces.context.servlet.ServletExternalContextImpl.encodeRedirectURL(ServletExternalContextImpl.java:455) at javax.faces.context.ExternalContextWrapper.encodeRedirectURL(ExternalContextWrapper.java:101) at javax.faces.context.ExternalContextWrapper.encodeRedirectURL(ExternalContextWrapper.java:101) at org.apache.myfaces.application.ViewHandlerImpl.getRedirectURL(ViewHandlerImpl.java:175) at javax.faces.application.ViewHandlerWrapper.getRedirectURL(ViewHandlerWrapper.java:142) at org.apache.webbeans.jsf.ConversationAwareViewHandler.getRedirectURL(ConversationAwareViewHandler.java:89) at javax.faces.application.ViewHandlerWrapper.getRedirectURL(ViewHandlerWrapper.java:142)
Is it possible to pass empty value somehow?
Thanks
Milan Siebenbürger