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 ответа

Решение

Короткий ответ:

  1. BigDecimalConverter.convertToString не вызывается, потому что он не используется.

    Есть ли другой способ добиться этого (без определения соответствующего поля String и / или получателя String)?

  2. Нет, ты не можешь. 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();
    }
    ...
}
Другие вопросы по тегам