This is an automated email from the ASF dual-hosted git repository.

nmalin pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 82f25f6192 Fixed: Json response failed when element not serializable 
(OFBIZ-12621)
82f25f6192 is described below

commit 82f25f619228cf50a3a7a2e6726e24b3cc94298d
Author: Nicolas Malin <nicolas.ma...@nereide.fr>
AuthorDate: Wed May 25 14:35:36 2022 +0200

    Fixed: Json response failed when element not serializable (OFBIZ-12621)
    
    When you forward a request-map on json response after a service call like 
this :
    
         <request-map uri="updateMyEntity">
            <security https="true" auth="true"/>
            <event type="service" invoke="serviceWithUnserializableElement"/>
            <response name="success" type="request" value="json"/>
            <response name="error" type="request" value="json"/>
        </request-map>
    
    The request json works fine if the serviceWithUnserializableElement have an 
element unserializable on out put at the first level
    
         <service name="serviceWithUnserializableElement"...>
            <attribute name="outputStream" type="java.io.OutputStream" 
mode="OUT"/>
         </service>
    
    If the definition is like this
    
         <service name="serviceWithUnserializableElement"...>
            <attribute name="outputStreamMap" type="Map" mode="OUT"/>
         </service>
    
    The json failed to generate if the outputStream is a map. despite the 
function UtilHttp.getJSONAttributeMap that safe only the first map level and 
don't work in deep.
    
    By the way, we improved the getJSONAttributeMap to work in deep by a 
recursive treatment on Map and List.
---
 .../java/org/apache/ofbiz/base/util/UtilHttp.java  | 48 ++++++++++++++++------
 1 file changed, 36 insertions(+), 12 deletions(-)

diff --git 
a/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilHttp.java 
b/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilHttp.java
index cc1989a1cd..2edcc8e5e7 100644
--- a/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilHttp.java
+++ b/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilHttp.java
@@ -461,25 +461,49 @@ public final class UtilHttp {
      * @return The resulting Map
      */
     public static Map<String, Object> getJSONAttributeMap(HttpServletRequest 
request) {
+        return parseJSONAttributeMap(getAttributeMap(request));
+    }
+
+    /**
+     * For a map analyse each object to prepare a Json response
+     * @param attrMap
+     * @return
+     */
+    private static Map<String, Object> parseJSONAttributeMap(Map<String, 
Object> attrMap) {
         Map<String, Object> returnMap = new HashMap<>();
-        Map<String, Object> attrMap = getAttributeMap(request);
         for (Map.Entry<String, Object> entry : attrMap.entrySet()) {
-            String key = entry.getKey();
-            Object val = entry.getValue();
-            if (val instanceof java.sql.Timestamp) {
-                val = val.toString();
-            }
-            if (val instanceof String || val instanceof Number || val 
instanceof Map<?, ?> || val instanceof List<?> || val instanceof Boolean) {
-                if (Debug.verboseOn()) {
-                    Debug.logVerbose("Adding attribute to JSON output: " + 
key, MODULE);
-                }
-                returnMap.put(key, val);
+            Object val = parseJSONAttributeValue(entry.getValue());
+            if (val != null) {
+                returnMap.put(entry.getKey(), val);
             }
         }
-
         return returnMap;
     }
 
+    /**
+     * For a value analyse the object type to prepare a Json response
+     * @param val
+     * @return
+     */
+    private static Object parseJSONAttributeValue(Object val) {
+        if (val == null) {
+            return null;
+        }
+        if (val instanceof java.sql.Timestamp) {
+            val = val.toString();
+        }
+        if (val instanceof String
+                || val instanceof Number
+                || val instanceof Boolean) {
+            return val;
+        } else if (val instanceof Map<?, ?>) {
+            return parseJSONAttributeMap(UtilGenerics.cast(val));
+        } else if (val instanceof List<?>) {
+            return ((List) 
val).stream().map(UtilHttp::parseJSONAttributeValue).collect(Collectors.toList());
+        }
+        return null;
+    }
+
     /**
      * Create a map from a HttpRequest (attributes) object
      * @return The resulting Map

Reply via email to