From 617b42893df49d6d05d1c4213932d1a6c939e77c Mon Sep 17 00:00:00 2001 From: Klaus Richarz Date: Tue, 17 Dec 2024 21:44:00 +0100 Subject: [PATCH] Add Struts converters initialization to prevent GC issues Bind custom converters to the ServletContext to ensure they are not garbage collected when "convertNull" is enabled. This includes handling null-safe conversions for types like BigDecimal, Boolean, and Integer. Also, deregisters and re-registers default converters accordingly. --- .../struts/DelegatingRequestProcessor.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/main/java/org/tb/common/struts/DelegatingRequestProcessor.java b/src/main/java/org/tb/common/struts/DelegatingRequestProcessor.java index 85c289f4..c3746e06 100644 --- a/src/main/java/org/tb/common/struts/DelegatingRequestProcessor.java +++ b/src/main/java/org/tb/common/struts/DelegatingRequestProcessor.java @@ -5,8 +5,24 @@ import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; import java.io.IOException; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.HashMap; +import java.util.Map; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.beanutils.ConvertUtils; +import org.apache.commons.beanutils.Converter; +import org.apache.commons.beanutils.converters.BigDecimalConverter; +import org.apache.commons.beanutils.converters.BigIntegerConverter; +import org.apache.commons.beanutils.converters.BooleanConverter; +import org.apache.commons.beanutils.converters.ByteConverter; +import org.apache.commons.beanutils.converters.CharacterConverter; +import org.apache.commons.beanutils.converters.DoubleConverter; +import org.apache.commons.beanutils.converters.FloatConverter; +import org.apache.commons.beanutils.converters.IntegerConverter; +import org.apache.commons.beanutils.converters.LongConverter; +import org.apache.commons.beanutils.converters.ShortConverter; import org.apache.struts.Globals; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; @@ -37,6 +53,31 @@ public void init(ActionServlet actionServlet, ModuleConfig moduleConfig) throws protected WebApplicationContext initWebApplicationContext(ActionServlet actionServlet) throws IllegalStateException { WebApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext(actionServlet.getServletContext()); context.getServletContext().setAttribute("salatProperties", context.getBean(SalatProperties.class)); + + // ensure converters are bound to servlet context to not get garbage collected + String convertNull = actionServlet.getServletConfig().getInitParameter("convertNull"); + if ("true".equalsIgnoreCase(convertNull) || "yes".equalsIgnoreCase(convertNull) + || "on".equalsIgnoreCase(convertNull) || "y".equalsIgnoreCase(convertNull) + || "1".equalsIgnoreCase(convertNull)) { + + Map, Converter> converters = new HashMap<>(); + converters.put(BigDecimal.class, new BigDecimalConverter(null)); + converters.put(BigInteger.class, new BigIntegerConverter(null)); + converters.put(Boolean.class, new BooleanConverter(null)); + converters.put(Byte.class, new ByteConverter(null)); + converters.put(Character.class, new CharacterConverter(null)); + converters.put(Double.class, new DoubleConverter(null)); + converters.put(Float.class, new FloatConverter(null)); + converters.put(Integer.class, new IntegerConverter(null)); + converters.put(Long.class, new LongConverter(null)); + converters.put(Short.class, new ShortConverter(null)); + + context.getServletContext().setAttribute("struts.converters", converters); + + ConvertUtils.deregister(); + converters.forEach((clazz, converter) -> ConvertUtils.register(converter, clazz)); + } + return context; }