Jersey / JAXB讨厌Rectangle

时间:2017-11-06 17:46:49

标签: java jaxb jersey

我有一个使用Jersey进行REST服务的Java应用程序。我有几个REST端点,所有这些端点都返回有效的JSON(所需的格式)。我们有一个新的端点,一个GET,它返回有效的JSON,除了一个元素,一个Java Rectangle。这是我们得到的回应:

[
    {
        "customers": {
            "current": 2,
            "max": 16
        },
        "format": "ABCD",
        "dataPoints": 20,
        "window": "java.awt.Rectangle[x=50,y=50,width=400,height=300]"
    }
]

如您所见,Rectangle不是有效的JSON。我尝试了几件事,但都没有奏效。我尝试过的内容包括在类的Rectangle元素上添加@XmlRootElement@XmlElement@XmlAttribute。唯一能做的就是将格式错误的JSON移到输出顶部。

我怀疑它不起作用,因为Rectangle类在其类声明中没有@XmlRootElement,因此JAXB无法正确地将其转换为XML(然后转换为JSON) 。如果是这种情况,我是否需要继承Rectangle才能包含该注释?似乎JAXB开发人员会考虑内置类型。我的假设是正确的,还是有另一种解决方案?

2 个答案:

答案 0 :(得分:1)

另一种解决方案可能是自己进行JSON转换,然后将JSON字符串作为Response的实体返回,如下所示。

@Path("/rectangle")
@Produces(MediaType.APPLICATION_JSON)
@GET
public Response getRect() {

    Rectangle r = new Rectangle();
    Gson gson = new Gson();
    String jsonRect = gson.toJson(r);
    return Response.status(Status.OK).entity(jsonRect).build();
}

因此根本不使用JAXB。

答案 1 :(得分:1)

关注this article,你可以解决这个问题。

JAXB开箱即用,无法编组/解组java.awt.Rectangle

因为我们无法更改Rectangle类,所以我们将编写一个新类MyRectangle,JAXB知道如何编组/解组。

public class MyRectangle {

    private int x;
    private int y;
    private int width;
    private int height;

    public MyRectangle() {
    }

    public MyRectangle(int x, int y, int width, int height) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }
}

然后我们需要XmlAdapter 用于在RectangleMyRectangle之间进行转换:

public class RectangleXmlAdapter extends XmlAdapter<MyRectangle, Rectangle> {

    @Override
    public Rectangle unmarshal(MyRectangle v) throws Exception {
        if (v == null)
            return null;
        return new Rectangle(v.getX(), v.getY(), v.getWidth(), v.getHeight());
    }

    @Override
    public MyRectangle marshal(Rectangle v) throws Exception {
        if (v == null)
            return null;
        return new MyRectangle(v.x, v.y, v.width, v.height);
    }
}

最后,您使用@XmlJavaTypeAdapter 在编组/解组时告诉JAXB使用我们的RectangleXmlAdapter的注释 Rectangle属性。例如:

@XmlJavaTypeAdapter(RectangleXmlAdapter.class)
private Rectangle window;

然后这个window属性将具有这样的XML表示:

<window>
    <x>50</x>
    <y>50</y>
    <width>400</width>
    <height>300</height>
</window>

然后(通过一些Jersey-magic)这样的JSON表示:

"window": {
    "x": 50,
    "y": 50,
    "width": 400,
    "height": 300
}