Struts2 BigDecimal Converter does not convert to String

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 a request is sent with some large decimal "12345678901234567890.123456789123456789" , the convertFromString method is convertFromString and the value is converted to a string and prints

 BigDecimal : Converting from String : 12345678901234567890.123456789123456789 

But when analyzing the response, the convertToString method convertToString not executed, since it does not register the expected string on standard output. Struts2 internally converts BigDecimal to String and returns a response.

 {"bigField":12345678901234567890.123456789123456789} 

When the response is received in JavaScript, it becomes 12345678901234567000 , a big loss of value.


Questions:

  • Why isn't BigDecimalConverter.convertToString called?
  • Is there any other way to achieve this (without defining the appropriate String and / or String getter field)?
+6
source share
2 answers

Short answer:

  • BigDecimalConverter.convertToString not called because it is not used.

    Is there any other way to achieve this (without defining the appropriate String field and / or String getter)?

  • No, you can’t. JavaScript is not your choice of language, or you can use it as a string. This means that you can overcome the language restriction with bigdecimal.js .

+1
source

Some possible solutions to resolve it.

Use pseudo-thermal

 public String getBigFieldString() { return bigField != null ? bigField.toPlainString : null; } 

and the plugin will serialize it as bigFieldString:"12345678901234567890.123456789123456789" . You can also use a field receiver.


Change JSON connection code Copy the org.apache.struts2.json.JSONWriter class from the JSON Plugin into the project code. and update the process method as shown below. (Be careful with 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(); } ... } 
+5
source

All Articles