2017-11-06 8 views
0

REST 서비스를 위해 Jersey를 사용하는 Java 애플리케이션이 있습니다. 몇 가지 REST 엔드 포인트가 있는데 모두 유효한 JSON (원하는 형식)을 리턴합니다. 하나의 요소 인 자바 사각형을 제외하고 유효한 JSON을 반환하는 새로운 종점 인 GET이 있습니다. 다음과 같은 응답입니다.Jersey/JAXB hates Rectangle

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

알다시피,이 사각형은 유효한 JSON이 아닙니다. 나는 여러 가지를 시도했지만 아무도 효과가 없었다. 내가 시도한 것들은 클래스의 Rectangle 요소에 @XmlRootElement, @XmlElement@XmlAttribute을 추가하는 것을 포함합니다. 유일한 것은 잘못된 형식의 JSON을 출력 상단으로 이동하는 것입니다.

Rectangle 클래스의 클래스 선언에 @XmlRootElement이 없기 때문에 JAXB를 올바르게 XML로 변환 할 수없고 JSON으로 변환 할 수 없다고 생각됩니다. 이 경우 해당 주석을 포함하기 위해 Rectangle에서 상속해야합니까? JAXB 개발자가 내장형을 고려한 것처럼 보입니다. 내 가정이 맞습니까? 아니면 다른 해결책이 있습니까?

+1

@XmlJavaTypeAdapter(RectangleXmlAdapter.class) private Rectangle window; 

다음이 window 속성은이 같은 XML 표현을해야합니다 'java.awt.Rectangle'을위한'XmlAdapter'를 만들어야합니다. [이 기사] (http://www.eclipse.org/eclipselink/documentation/2.6/moxy/advanced_concepts006.htm#TLJAX424)를 참조하십시오. –

+1

[JAXB의 java.awt.Point 및 java.awt.Rectangle]에 관련됨 (https://stackoverflow.com/questions/32070513/java-awt-point-and-java-awt-rectangle-in-jaxb) –

+0

고마워, 토마스 프리츠. 예제를 정확하게 복사했는데 이제는 'window'가 빈 배열로 표시됩니다. 그게 잘못이지만,이 오류를 디버깅하는 방법을 모른다. – Frecklefoot

답변

1

this article 다음으로이 문제를 해결할 수 있습니다.

JAXB는 기본 제공이며 마샬링/언 마샬링을 할 수 없습니다 java.awt.Rectangle.

Rectangle 클래스를 변경할 수 없기 때문에 JAXB가 마샬링/언 마샬링하는 방법을 알고있는 MyRectangle이라는 새로운 클래스를 작성합니다. 마지막으로, 우리는 RectangleXmlAdapter/정렬 화 Rectangle 속성을 비 정렬 할 때 사용할 JAXB에게하는 @XmlJavaTypeAdapter 주석을 사용

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); 
    } 
} 

: Rectangle 사이 MyRectangle

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 이 필요합니다. 예를 들면 다음과 같은 JSON 표현 다음

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

및 (일부 뉴저지 - 마술) :

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

고마워! 나는 이미 기사를 따라 가면서이 작업을 수행했지만 깊이있는 답변을 주셔서 감사합니다! 일단 JAXB가 클래스를 XML로 변환 할 수 있다면 JSON으로 변환 할 수 있다는 것을 알았습니다. 다시 한 번 감사드립니다! – Frecklefoot

+1

XML-JSON 변환에 대한 귀하의 노트에 따라 답변을 업데이트했습니다. –

1

대체 해결책은 JSON 변환을 직접 수행 한 다음 아래 그림과 같이 JSON 문자열을 응답의 엔터티로 반환하는 것입니다.

@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를 전혀 사용하지 않습니다.

+0

제안 해 주셔서 감사합니다. 그러나이 방법은 효과가 없습니다. 내 REST 엔드 포인트는 리턴해야하는 데이터가있는 다른 클래스를 호출합니다. 제안을 사용하면 getRect()가 호출되지 않습니다 (아마도 문자열이 반환되고 Rectangle이 아니기 때문일 수 있습니다). 어쨌든 고마워. – Frecklefoot