【问题标题】:Jersey mangles data from JSON?泽西破坏来自 JSON 的数据?
【发布时间】:2017-12-01 21:40:53
【问题描述】:

我们有一个使用 Jersey 框架实现的 REST Web 服务,它允许用户从 UI 保存配置信息。有一个 GET(获取当前配置信息)和一个相应的 POST 来保存设置。该数据保存在 JSON 文件中。 GET 完美运行,POST exept 也适用于一个值:

"modulation": 2,

无论此值设置为什么,在 POST 中从 UI 获取数据时,它始终是默认值。其他所有值都是完美的。

这个值曾经是一个枚举,因为文件中的所有内容都保存为intString,我认为这可能会造成混淆。所以我把它改成了int。那没有帮助。从好的方面来说,它也没有让事情变得更糟。

使用优秀的邮递员,我发送一个带有 POST 的 JSON 结构:

{
    "customers": {
        "max": 20,
        "current": 2
    },
    "window": {
        "x": 10,
        "y": 10,
        "width": 20,
        "height": 20
    },
    "modulation": 2,    // always just the default, 1
    "pointsOfConsternation": 20
}

它会自动转换为我们用于配置的对象。除了讨厌的mode 之外,所有值都正确出现。下面是接收方法签名的样子:

@POST
@Consumes({MediaType.APPLICATION_JSON})
@Produces(MediaType.TEXT_PLAIN)
@Path("/config")
public String setConfiguration( ConsternationConfig config ) {
    ...
    // do magic
    ...
}

我已经调试了它的废话,但无济于事。修改发生在我无法控制的代码中。它进入 POST 方法被破坏。

知道会发生什么吗?

更新 根据@Aleh Maksimovich,这是ConsternationConfig 的来源:

@XmlRootElement
public class ConsternationConfig {

    // Data members
    private Customers customers;
//  private ConsternationModulation modulation; // how modulation used to be defined, changed to the int below
    private int modulation;
    private int pointsOfConsternation;

    @XmlJavaTypeAdapter(RectangleStandInAdapter.class)
    private Rectangle window;

    /**
     * Default constructor
    */
    public ConsternationConfig() {
        customers = new Customers();
//      modulation = DEFAULT_MODULATION;  // how modulation used to be defined
        modulation = DEFAULT_MODULATION.ordinal();
        pointsOfConsternation= DEFAULT_POINTS_OF_CONSTERNATION;
        window = new Rectangle(DEFAULT_WINDOW_X, DEFAULT_WINDOW_Y, DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT);
    }

    public ConsternationModulation getModulation() {
        return ConsternationModulation.values()[modulation];
    }

    public void setModulation(int modulation) {
        this.modulation = modulation;
    }

    public void setModulation(ConsternationModulation modulation) {
        this.modulation = modulation.ordinal();
    }

...a whole bunch of other getters and setters that do nothing but set individual members...
}

这里的ConsternationModulation 只是为了更好的衡量:

public enum ConsternationModulation {

    INVALID,
    FIRST_CONSTERNATION,
    SECOND_CONSTERNATION,
    THIRD_CONSTERNATION,
    FOURTH_CONSTERNATION
}

【问题讨论】:

  • 您是否尝试使用 String 参数来查看它是否确实进入“mangled”?
  • 请将您的ConsternationConfig 来源添加到问题中。
  • @peeskillet,一旦我完成了一些其他的东西,我会尽快处理的。好主意啊。啊,添加了质疑的来源。
  • 我不明白。为什么你认为"mode" 应该反序列化为modulation?名称需要匹配。
  • 因为你还有枚举方法。这就是正在使用的东西。我不确定具有相同名称设置器方法的确切规则是什么。至于选择哪一个,我不确定是什么指导了这一点。但我认为这是问题所在。

标签: java json rest jersey


【解决方案1】:

问题在于我有 两个 setModulation() 方法。一个允许modulation 设置为int,另一个允许设置为枚举。我认为对话足够聪明,可以调用适当的 setter(int setter)。我错了。显然,有两个二传手混淆了转换器,所以它也没有调用。这就解释了为什么它总是使用默认值(在构造函数中设置)。

删除 setter 的枚举版本解决了这个问题,之后它运行良好。上面显示了设置器,但为了方便起见,这里再次显示。它没有什么特别或神奇的地方:

public void setModulation(int modulation) {
    this.modulation = modulation;
}

感谢所有输入,尤其是 peeskillet!

【讨论】:

    猜你喜欢
    • 2016-10-23
    • 2013-11-26
    • 2015-03-10
    • 2011-10-14
    • 2015-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多