问题
I am a .NET Developer learning Java. Please see the code below:
The class HelloWorld
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PUT;
import javax.ws.rs.core.MediaType;
@Path("generic")
public class HelloWorld {
@Context
private UriInfo context;
public HelloWorld() {
}
@GET
@Produces("application/xml")
public String getHtml() {
return "<?xml version='1.0'?><PARTS><TITLE>Computer Parts</TITLE><PART><ITEM>Motherboard</ITEM></PART></PARTS>";
}
}
The class JavaApplication3
package javaapplication3;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.stream.Collectors;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import sun.misc.IOUtils;
/**
*
* @author 3212627
*/
public class JavaApplication3 {
private static String charset;
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws MalformedURLException, IOException, JAXBException {
//Get the URI by selecting the RESTful web services folder under the web app project. Then right click on the underlying node
//and select: TestResourceURI
String content;
String uri ="http://localhost:8080/HelloRestService/webresources/generic";
URL url = new URL(uri);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
//connection.setRequestProperty("Accept", "application/xml");
connection.setRequestProperty("Accept", "application/xml");
JAXBContext jc = JAXBContext.newInstance(String.class); //I changed Customer.class to String.class
InputStream xml = connection.getInputStream();
String str = (String) jc.createUnmarshaller().unmarshal(xml); //line causing exception
connection.disconnect();
}
}
The exception returned is:
Exception in thread "main" javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"PARTS"). Expected elements are (none)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:726)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:247)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:242)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:109)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1131)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:556)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:538)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:153)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:380)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(XMLNSDocumentScannerImpl.java:619)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3129)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:880)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:118)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:504)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:243)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:214)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:204)
at javaapplication3.JavaApplication3.main(JavaApplication3.java:46)
Java Result: 1
BUILD SUCCESSFUL (total time: 5 seconds)
I have marked the line that causes the exception. What is the problem?
回答1:
The main purpose of JAXB
is to do the mapping between XML
and a Java Bean
but to be able to do it, it relies on annotations from javax.xml.bind.annotation
that you need to declare on the fields or on the getters of your target Java Bean.
So for example here, your mapping could be defined as next:
The class Parts
public class Parts {
@XmlElement(name = "TITLE")
private String title;
@XmlElement(name = "PART")
private List<Part> parts;
public String getTitle() {
return this.title;
}
public void setTitle(final String title) {
this.title = title;
}
public List<Part> getParts() {
return this.parts;
}
public void setParts(final List<Part> parts) {
this.parts = parts;
}
}
The class Part
@XmlAccessorType(XmlAccessType.FIELD)
public class Part {
@XmlElement(name = "ITEM")
private String item;
public String getItem() {
return this.item;
}
public void setItem(final String item) {
this.item = item;
}
}
Once you have your mapping defined, you need to provide it to your JAXBContext
to be able to unmarshal
your XML
content to get an instance of the class Parts
:
JAXBContext jc = JAXBContext.newInstance(Parts.class);
InputStream xml = connection.getInputStream();
Parts parts = (Parts) jc.createUnmarshaller().unmarshal(xml);
Here is a good tutorial about JAXB
that you should read. You should also read the one from oracle.
来源:https://stackoverflow.com/questions/40214801/exception-in-thread-main-javax-xml-bind-unmarshalexception