Struts2 BigDecimal Converter is not converting to String
У меня есть следующий код:
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>
наблюдение
Когда запрос подается с большим десятичным знаком "12345678901234567890.123456789123456789"
метод convertFromString
выполняется и значение преобразуется в строку и печатает
BigDecimal : Converting from String : 12345678901234567890.123456789123456789
Но когда ответ анализируется, метод convertToString
не выполняется, так как не записывает ожидаемую строку в стандартный вывод. Struts2 внутренне конвертирует BigDecimal
в String
и следующий ответ возвращается.
{"bigField":12345678901234567890.123456789123456789}
Когда ответ получен в JavaScript, он становится 12345678901234567000
, большая потеря стоимости.
Вопросы:
- Зачем
BigDecimalConverter.convertToString
не вызывается? - Есть ли другой способ добиться этого (без определения соответствующего
String
поле и / илиString
геттер)?
2 ответа
Короткий ответ:
BigDecimalConverter.convertToString
не вызывается, потому что он не используется.Есть ли другой способ добиться этого (без определения соответствующего поля String и / или получателя String)?
Нет, ты не можешь. JavaScript не ваш выбор языка, или вы можете использовать его в качестве строки. Означает, что ограничение языка вы можете преодолеть с помощью чего-то вроде
bigdecimal.js
,
Некоторые возможные решения, чтобы решить это.
Используйте псевдо-добытчик
public String getBigFieldString() {
return bigField != null ? bigField.toPlainString : null;
}
и плагин будет сериализовать его как bigFieldString:"12345678901234567890.123456789123456789"
, Вы также можете использовать геттер поля, чтобы сделать это.
Изменить копию кода плагина JSON org.apache.struts2.json.JSONWriter
класс из плагина JSON в код вашего проекта. и обновить process
метод, как показано ниже. (Будьте осторожны при этом.)
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();
}
...
}