【问题标题】:Struts2 BigDecimal Converter is not converting to StringStruts2 BigDecimal 转换器未转换为字符串
【发布时间】:2014-05-13 15:54:59
【问题描述】:

我有以下代码:

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 getter)?

【问题讨论】:

  • 是 12345678901234567890 而不是 123456789123456789 是错字吗?
  • 是的,我已经更新了问题...感谢您指出...

标签: java javascript struts2 bigdecimal struts2-json-plugin


【解决方案1】:

简答:

  1. BigDecimalConverter.convertToString 未被调用,因为它未被使用。

    有没有其他方法可以实现这个(没有定义对应的 字符串字段和/或字符串 getter)?

  2. 不,你不能。 JavaScript 不是您的语言选择,或者您可以将其用作字符串。意味着您可以通过 bigdecimal.js 之类的方式克服语言限制。

【讨论】:

  • 我已经在使用bigdecimal.js。但我们首先需要一个完整值的字符串。如题所示,bigField不是字符串,在javascript中被解释为数字。
  • 我没看懂it isn't used的说法。因为当我调用 processBig.action 并使用 bigField 的某个值时,它会使用其 setter 在操作上填充,调用 execute 方法,并使用其 getter 方法返回 json 响应。
  • json 响应不使用 struts 转换器。
【解决方案2】:

一些可能的解决方案来解决它。

使用伪 getter

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

插件会将其序列化为bigFieldString:"12345678901234567890.123456789123456789"。您也可以使用字段的 getter 来执行此操作。


更改 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();
    }
    ...
}

【讨论】:

  • 像魅力一样工作。该插件应该像这样处理BigDecimal
猜你喜欢
  • 2018-11-29
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-16
相关资源
最近更新 更多