Tomcat 7에 배포 할 RestEasy 2.2.2를 사용하여 JAX-RS 웹 서비스를 개발 중입니다. 서비스는 JAXB를 사용하여 XML을 반환합니다 (반환해야 함). 반환 된 XML은이 다음 코드를 사용하는 방법과 유사 ConcurrentHashMap의의 표현을 포함해야한다 :RestEasy와 Tomcat을 사용하여 HashMap에서 MessageBodyWriter를 사용하려면 어떻게해야합니까?
이@XmlRootElement(name="items")
@XmlAccessorType(XmlAccessType.NONE)
public class ItemCollection
{
@XmlElement(name="item")
private ConcurrentHashMap<String, Item> items;
public ItemCollection()
{
items = new ConcurrentHashMap<String, item>();
// fill the map
}
}
Item
클래스는 XML로 직렬화 될 필요가있는 ConcurrentHashMap
이 포함되어 있습니다.
이
리소스 클래스입니다 : 이@Path("/items")
public class ItemResource
{
@GET
@Produces(MediaType.APPLICATION_XML)
public ItemCollection getAllItems()
{
// get itemManager
return itemManager.getItems(); // ItemManager holds an instance of ItemCollection
}
}
이 코드는 실행하지만 내용이있는 XML을 생성합니다
<items>
<item/>
</items>
내가 출력 으려고 시도하고 같은입니다
<items>
<item id="...">
<data>...</data>
<otheritems>
<otheritem id="...">
<someotherdata>...</someotherdata>
</otheritem>
</otheritems>
</item>
<item id="...">
<data>...</data>
<otheritems>
<otheritem id="...">
<someotherdata>...</someotherdata>
</otheritem>
<otheritem id="...">
<someotherdata>...</someotherdata>
</otheritem>
<otheritem id="...">
<someotherdata>...</someotherdata>
</otheritem>
</otheritems>
</item>
</items>
MessageBodyWriter
구현은 내장 기능 i 충분하지 않습니다. ConcurrentHashMap
을 마샬링하기 위해 MessageBodyWriter
구현을 시도했지만 지금까지 작동하지 못했습니다. 즉, 코드를 호출 할 수 있지만 여러 가지 예외로 중지됩니다.
MessageBodyWriter
(및 MessageBodyReader
) 인터페이스를 구현하고 사용해야하는 방법을 잘 모르겠습니다. 빌 버크 (Bill Burke)의 "RESTful Java with JAX-RS"책이 있습니다. JAX-RS 서비스 설계에 도움이되지만 관련 섹션의 MessageBodyWriter
기능에 대한 자세한 내용을 찾을 수 없습니다. 내 인터넷 검색은 올바른 방향으로 나를 인도 할 수있는 것을 산출하지 못했습니다.
아무도 나를 MessageBodyWriter
(및 MessageBodyReader
) 인터페이스를 올바르게 구현하는 방법을 이해하는 데 도움이된다면 고맙겠습니다. 내가 주석을 놓치고 있는지, 하나를 잘못 놓고 있는지, 완전히 새로운 접근이 필요한지 나는 모른다.
도움을 주셔서 미리 감사드립니다.
편집 :
다음에 코드를 수정하는 것은 중간이 저를 가져옵니다
@XmlRootElement(name="items")
@XmlAccessorType(XmlAccessType.NONE)
public class ItemCollection
{
private ConcurrentHashMap<String, Item> items;
public ItemCollection()
{
items = new ConcurrentHashMap<String, item>();
// fill the map
}
@XmlElement(name="item")
public Collection<Item> getItems()
{
return items.values();
}
}
이 내가 (샘플 위 포함) 필요한 XML을 생성합니다. 그러나 언 마샬링 할 때는이 코드가 작동하지 않습니다.
java.lang.UnsupportedOperationException
java.util.AbstractCollection.add(AbstractCollection.java:221)
com.sun.xml.internal.bind.v2.runtime.reflect.Lister$CollectionLister.addToPack(Lister.java:290)
com.sun.xml.internal.bind.v2.runtime.reflect.Lister$CollectionLister.addToPack(Lister.java:254)
com.sun.xml.internal.bind.v2.runtime.unmarshaller.Scope.add(Scope.java:106)
com.sun.xml.internal.bind.v2.runtime.property.ArrayERProperty$ReceiverImpl.receive(ArrayERProperty.java:195)
com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.endElement(UnmarshallingContext.java:507)
com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.endElement(SAXConnector.java:145)
com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:601)
com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(XMLDocumentFragmentScannerImpl.java:1782)
com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2938)
com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648)
com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)
com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:511)
com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:808)
com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:119)
com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:200)
com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:173)
javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:137)
javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:142)
javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:151)
javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:169)
// ... the rest
나는 이유는 Unmarshaller에이 Collection
에 항목을 추가하려고하지 않습니다 있도록 "적절한 세터"의 부족이다 가정하지만 그 세터의 모습 방법을 모른다 : 나는 다음과 같은 예외가 . 누구든지이 작업을 수행하는 방법을 알고 있다면 도움을 주시면 감사하겠습니다.
미리 감사드립니다.
편집 2 : 그가 @XmlJavaTypeAdapter
를 사용하여 제안 곳 BTW
, 나는 크리스 '답장을 보았다. 제안을 시도한 결과 필요한 XML에 가깝게 다가 왔습니다.그러나 @XmlJavaTypeAdapter를 사용하여 얻은 XML에는 대신 <class><items><item>
이라는 추가 레벨이 있습니다. 예제에서 볼 수 있듯이 ConcurrentHashMap
인스턴스가 클래스의 멤버 변수로 사용됩니다. 또한 개별지도 항목의 요소 이름을 변경할 수없는 것처럼 보입니다 (항상 "항목"이라고 함).
위의 내용은 큰 문제가 아니며 필자는 필요한 경우 변경하고 필요에 따라 함께 살 수 있습니다. 그러나 가능하다면, 나는 처음부터 그것들을 갖고 싶지 않습니다. 교육적 목적을 위해서, 나는 EDIT 1의 코드가 언 마샬링 (unmarshalling)을 위해 작동하지 않는다는 것과 왜 가능하면 그것을 고치는 지 이해하고 싶다.
미리 도움을 청하십시오.
이 세부적인 답변을 작성해 주셔서 감사합니다. 나는 그것을 시도하고 그것이 내가 필요로하는 XML 근처에 나를 가져온다. 나는 어댑터를 구현하는 동안 몇 가지 문제에 부딪 혔고이를 포함하도록 내 게시물을 편집했습니다. 빨리 살펴보고 뭔가 제안 할 수 있는지 확인해 주시면 감사하겠습니다. – alokoko