我正在开发一个基于 REST 的球衣实现的项目,我使用 JPA 进行持久性,使用 Spring IoC 进行 DI。现在我有一些必须用 JAXB (MOXy) 编组的对象。按照这个教程一步一步我试图让事情顺利进行,但不幸的是我还没有成功。以下是我的课程,如果你能帮忙请:
根类:
package com.persistent.entity;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement
public class Bar {
private Map<String,String> mapbar;
public Bar() {
}
public Bar(Map<String,String> map ){
this.mapbar = map;
}
@XmlJavaTypeAdapter(MapAdapter.class)
public Map<String, String> getMapbar() {
return mapbar;
}
public void setMapbar(Map<String, String> map) {
this.mapbar = map;
}
}
地图适配器类:
package com.persistent.entity;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
//import javax.xml.bind.JAXBContext;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class MapAdapter extends XmlAdapter<AdaptedMap, Map<String, String>> {
@Override
public AdaptedMap marshal(Map<String, String> map) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.newDocument();
Element rootElement = document.createElement("bar");
document.appendChild(rootElement);
for(Entry<String,String> entry : map.entrySet()) {
Element mapElement = document.createElement(entry.getKey());
mapElement.setNodeValue(entry.getValue());
rootElement.appendChild(mapElement);
}
AdaptedMap adaptedMap = new AdaptedMap();
adaptedMap.setValue(document);
return adaptedMap;
}
@Override
public Map<String, String> unmarshal(AdaptedMap adaptedMap) throws Exception {
Map<String, String> map = new HashMap<String, String>();
Element rootElement = (Element) adaptedMap.getValue();
NodeList childNodes = rootElement.getChildNodes();
for(int x=0,size=childNodes.getLength(); x<size; x++) {
Node childNode = childNodes.item(x);
if(childNode.getNodeType() == Node.ELEMENT_NODE) {
map.put(childNode.getLocalName(), childNode.getTextContent());
}
}
return map;
}
}
AdaptedMap 类:
package com.persistent.entity;
import javax.xml.bind.annotation.XmlAnyElement;
//import org.w3c.dom.Document;
public class AdaptedMap {
private Object value;
@XmlAnyElement
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
}
最后是资源类:
package com.persistent.rest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import com.persistent.entity.Bar;
import com.persistent.entity.BarList;
import com.persistent.entity.Pie;
import com.persistent.entity.Vente;
import com.persistent.entity.VentesList;
import com.persistent.entity.PieList;
import com.persistent.service.VenteService;
import com.sun.jersey.api.json.JSONWithPadding;
// The Java class will be hosted at the URI path "/myresource"
@Path("/myresource")
@Component
@Scope("request")
public class MyResource {
@Autowired
VenteService venteService;
@GET
@Produces("application/x-javascript")
public JSONWithPadding getBarService(@QueryParam("callback") String callback){
int i;
VentesList ventes = venteService.getAll();
Map<String,String> hmBar = new HashMap<String,String>();
for (i=0;i<ventes.getsimpleVentes().size();i++){
hmBar.put(ventes.getsimpleVentes().get(i).getProjet(),String.valueOf(
ventes.getsimpleVentes().get(i).getNbrRsrv()));
}
Bar ba = new Bar(hmBar);
return new JSONWithPadding(ba,callback);
}
}
在Tomcat上运行它后,我得到这个异常:
GRAVE: "Servlet.service()" pour la servlet Jersey Spring Web Application a généré une exception
java.io.IOException: Error marshalling JAXB object of type "class com.persistent.entity.Bar".
at com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.writeTo(AbstractRootElementProvider.java:145)
at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:254)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:578)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:502)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:493)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:308)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:314)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:239)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:619)
Caused by: javax.xml.bind.MarshalException
- with linked exception:
[Exception [EclipseLink-25003] (Eclipse Persistence Services - 2.3.1.v20111018-r10243): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: An error occurred marshalling the object
Internal Exception: Exception [EclipseLink-3001] (Eclipse Persistence Services - 2.3.1.v20111018-r10243): org.eclipse.persistence.exceptions.ConversionException
Exception Description: The object [{Dyar Al Baydae=6, TEST=8, test=5, Dyar Al Bahja=20, Dyar Al Mansour=87}], of class [class java.util.HashMap], could not be converted to [class com.persistent.entity.AdaptedMap].]
at org.eclipse.persistence.jaxb.JAXBMarshaller.marshal(JAXBMarshaller.java:326)
at com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.writeTo(AbstractRootElementProvider.java:167)
at com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.writeTo(AbstractRootElementProvider.java:143)
... 19 more