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