2017-11-19 1 views
0

Java 및 Spring 5.0.1을 사용하여 작은 REST 웹 서비스를 작성하고 XML 응답에 오류 코드가 표시되는 데 문제가 있습니다. 클래스는 "USERNAME_EXISTS"와 같이 열거 형 값 대신 표시하고 싶은 "code"및 "message"속성을 가지고 있습니다.XML을 요청할 때 REST 응답에 여러 속성이있는 열거 형 표시

사용자가 Json을 요청할 때 열거 형을 표시하려면 @JsonFormat 주석을 사용하고 있지만 XML을 요청할 때 같은 방식으로 표시하는 방법을 파악할 수는 없습니다. @XmlEnumValue 주석은 필자가 필요로하는 것과 가깝지만 한 가지 가치 만 갖는다.

누구나 내가 원하는 방식을 표시하는 방법에 대한 조언을 해 줄 수 있습니까? 또한 HttpStatus 필드가 같은 방식으로 동작하도록하여 "CONFLICT"대신 "409"및 "Conflict"를 표시 할 수 있습니다.

XML을 요청하면 Spring은 내 객체를 XML로 변환하기 위해 Jaxb2RootElementHttpMessageConverter을 사용합니다. 일부 Java 구성 및 일부 사용자 정의 Marshaller 구현이 작동하도록 작성해야합니까?

더 많은 코드 샘플을 제공해야하는지 알려주세요. 감사합니다.

@XmlRootElement(name="error_code") 
@XmlEnum 
@JsonFormat(shape = JsonFormat.Shape.OBJECT) 
public enum ErrorCode implements Serializable 
{ 
    USERNAME_EXISTS("1001", "The specified username already exists."), 
    EMAIL_IN_USE("1002", "The specified email address is already in use."); 

    private String code; 
    private String message; 

    private ErrorCode(String code, String message) 
    { 
     this.code = code; 
     this.message = message; 
    } 

    @XmlElement(name="code") 
    public String getCode() 
    { 
     return code; 
    } 

    @XmlElement(name="message") 
    public String getMessage() 
    { 
     return message; 
    } 
} 

내가 JSON을 요청하면, 열거 내가 원하는 방식으로 표시됩니다

여기 내 ErrorCode가 클래스입니다.

{ 
    "httpStatus": "CONFLICT", 
    "errorMessages": [ 
     { 
      "errorCode": { 
       "code": "1001", 
       "message": "The specified username already exists." 
      }, 
      "developerMessage": "User could not be created due to a conflict." 
     } 
    ] 
} 

그러나 요청 XML에는 열거 코드 및 값이 표시되지 않습니다.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<error_response> 
    <error_messages> 
     <developer_message>User could not be created due to a conflict.</developer_message> 
     <error_code>USERNAME_EXISTS</error_code> 
    </error_messages> 
    <http_status>CONFLICT</http_status> 
</error_response> 

답변

0

JAXB는 enumeration XML 형식으로 enum 클래스를 마샬링됩니다.

이것을 재정의하려면 @XmlJavaTypeAdapter 주석을 사용하여 XmlAdapter을 제공해야합니다. enum 유형을 보통 class 유형으로 변환해야하며 필요에 따라 주석을 달아야합니다.

예를 들어 XmlAdapterclass 유형을 enum의 정적 중첩 유형으로 모두 사용하여 유지하는 방법 중 하나가 여기에 해당됩니다.

@XmlJavaTypeAdapter(ErrorCode.Xml.Adapter.class) 
enum ErrorCode { 
    USERNAME_EXISTS("1001", "The specified username already exists."), 
    EMAIL_IN_USE("1002", "The specified email address is already in use."); 

    private final String code; 
    private final String message; 
    private ErrorCode(String code, String message) { 
     this.code = code; 
     this.message = message; 
    } 
    public String getCode() { 
     return this.code; 
    } 
    public String getMessage() { 
     return this.message; 
    } 

    @XmlAccessorType(XmlAccessType.FIELD) 
    @XmlType(propOrder = {"code", "message"}) 
    static final class Xml { 
     private String code; 
     private String message; 
     Xml(ErrorCode v) { 
      this.code = v.getCode(); 
      this.message = v.getMessage(); 
     } 

     static final class Adapter extends XmlAdapter<Xml, ErrorCode> { 
      @Override 
      public Xml marshal(ErrorCode v) throws Exception { 
       return new Xml(v); 
      } 
      @Override 
      public ErrorCode unmarshal(Xml v) throws Exception { 
       throw new UnsupportedOperationException(); 
      } 
     } 
    } 
} 

테스트

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
class XmlTest { 
    private ErrorCode errorCode; 
    public XmlTest() { 
    } 
    public XmlTest(ErrorCode errorCode) { 
     this.errorCode = errorCode; 
    } 
    public static void main(String[] args) throws Exception { 
     JAXBContext jaxbContext = JAXBContext.newInstance(XmlTest.class); 
     Marshaller marshaller = jaxbContext.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); 
     marshaller.marshal(new XmlTest(ErrorCode.EMAIL_IN_USE), System.out); 
    } 
} 

출력

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<xmlTest> 
    <errorCode> 
     <code>1002</code> 
     <message>The specified email address is already in use.</message> 
    </errorCode> 
</xmlTest> 
+0

이 트릭을 할해야처럼이 보인다! 매우 감사합니다! 질문이 있으면 다시 올께. – oapeter