I have the following code:
xwork-conversion.properties
java.math.BigDecimal=demo.BigDecimalConverter
BigDecimalConverter.java
package demo;
import java.math.BigDecimal;
import java.util.Map;
import org.apache.struts2.util.StrutsTypeConverter;
public class BigDecimalConverter extends StrutsTypeConverter{
@Override
public Object convertFromString(Map context, String[] values, Class clazz) {
System.out.println("BigDecimal : Converting from String : " + values[0]);
return new BigDecimal(values[0]);
}
@Override
public String convertToString(Map context, Object value) {
String str = ((BigDecimal)value).toPlainString();
System.out.println("BigDecimal : Converted to String : " + str);
return str;
}
}
TheAction.java
package demo;
//imports...
public class TheAction extends ActionSupport {
private BigDecimal bigField; //with getter and setter
public String execute() {
return SUCCESS;
}
}
struts.xml
<package name="demo" extends="json-default">
<action name="processBig" class="demo.TheAction">
<result type="json"/>
</action>
</package>
Observation
When request is submitted with some big decimal say "12345678901234567890.123456789123456789"
, method convertFromString
is executed and value is converted to string and prints
BigDecimal : Converting from String : 12345678901234567890.123456789123456789
But when response is parsed, method convertToString
is not executed as it does not log expected line on standard output. Struts2 internally converts BigDecimal
to String
and following response is returned.
{"bigField":12345678901234567890.123456789123456789}
When response is received in JavaScript, it becomes 12345678901234567000
, a big loss of value.
Questions:
BigDecimalConverter.convertToString
is not being called?String
field and/or String
getter)?Some possible solutions to resolve it.
Use a pseudo getter
public String getBigFieldString() {
return bigField != null ? bigField.toPlainString : null;
}
and plugin will serialize it as bigFieldString:"12345678901234567890.123456789123456789"
. You can also use field's getter to do this.
Change JSON Plugin Code
Copy org.apache.struts2.json.JSONWriter
class from JSON Plugin to your project code. and update process
method as below. (Be careful while doing this.)
package org.apache.struts2.json;
...
class JSONWriter {
...
private void process(Object object, Method method) throws JSONException {
this.stack.push(object);
if (object instanceof Class) {
this.string(object);
} else if (object instanceof Boolean) {
this.bool((Boolean) object);
}
// Begin: Handling of Big Decimal, Keep this code above Handling of Number
else if (object instanceof BigDecimal) {
this.string(((BigDecimal)object).toPlainString());
}
// End: Handling of Big Decimal
else if (object instanceof Number) {
this.add(object);
} else if (object instanceof String) {
this.string(object);
} else if (object instanceof Character) {
this.string(object);
} else if (object instanceof Map) {
this.map((Map) object, method);
} else if (object.getClass().isArray()) {
this.array(object, method);
} else if (object instanceof Iterable) {
this.array(((Iterable) object).iterator(), method);
} else if (object instanceof Date) {
this.date((Date) object, method);
} else if (object instanceof Calendar) {
this.date(((Calendar) object).getTime(), method);
} else if (object instanceof Locale) {
this.string(object);
} else if (object instanceof Enum) {
this.enumeration((Enum) object);
} else {
this.bean(object);
}
this.stack.pop();
}
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With