I'm trying to implement an xsd validator for schemas, that using imports and includes. I took this answer for example.
Here is my validating method:
public void validate(String filePath, String schemaName) throws Exception
{
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
factory.setResourceResolver(new ResourceResolver());
Source schemaFile = new StreamSource(getClass().getClassLoader().getResourceAsStream(schemaName));
Schema schema = factory.newSchema(schemaFile);
Validator validator = schema.newValidator();
validator.setErrorHandler(new MySAXParseErrorHandler());
validator.validate(new StreamSource(filePath));
}
LSInput (entirely the same):
public class LSInputImpl implements LSInput
{
private String publicId;
private String systemId;
public String getPublicId()
{
return publicId;
}
public void setPublicId(String publicId)
{
this.publicId = publicId;
}
public String getBaseURI()
{
return null;
}
public InputStream getByteStream()
{
return null;
}
public boolean getCertifiedText()
{
return false;
}
public Reader getCharacterStream()
{
return null;
}
public String getEncoding()
{
return null;
}
public String getStringData()
{
synchronized (inputStream) {
try {
byte[] input = new byte[inputStream.available()];
inputStream.read(input);
String contents = new String(input);
return contents;
} catch (IOException e) {
e.printStackTrace();
System.out.println("Exception " + e);
}
return null;
}
}
public void setBaseURI(String baseURI)
{
}
public void setByteStream(InputStream byteStream)
{
}
public void setCertifiedText(boolean certifiedText)
{
}
public void setCharacterStream(Reader characterStream)
{
}
public void setEncoding(String encoding)
{
}
public void setStringData(String stringData)
{
}
public String getSystemId()
{
return systemId;
}
public void setSystemId(String systemId)
{
this.systemId = systemId;
}
public BufferedInputStream getInputStream()
{
return inputStream;
}
public void setInputStream(BufferedInputStream inputStream)
{
this.inputStream = inputStream;
}
private BufferedInputStream inputStream;
public LSInputImpl(String publicId, String sysId, InputStream input)
{
this.publicId = publicId;
this.systemId = sysId;
this.inputStream = new BufferedInputStream(input);
}
}
ResourceResolver:
public class ResourceResolver implements LSResourceResolver
{
public LSInput resolveResource(String type, String namespaceURI,
String publicId, String systemId, String baseURI) {
InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(systemId);
return new LSInputImpl(publicId, systemId, resourceAsStream);
}
}
When I'm trying to validate xml with xsd that has only imports, it works fine. But when I split one schema with two by using include, process fails with IOException:
java.io.IOException: Stream closed
at java.io.BufferedInputStream.getInIfOpen(BufferedInputStream.java:159)
at java.io.BufferedInputStream.available(BufferedInputStream.java:410)
at LSInputImpl.getStringData(LSInputImpl.java:57)
at com.sun.org.apache.xerces.internal.util.DOMEntityResolverWrapper.resolveEntity(DOMEntityResolverWrapper.java:130)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.resolveEntity(XMLEntityManager.java:1073)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.resolveDocument(XMLSchemaLoader.java:659)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.resolveSchemaSource(XSDHandler.java:2105)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.constructTrees(XSDHandler.java:1088)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.constructTrees(XSDHandler.java:1120)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.parseSchema(XSDHandler.java:620)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadSchema(XMLSchemaLoader.java:616)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:574)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:540)
at com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory.newSchema(XMLSchemaFactory.java:255)
at javax.xml.validation.SchemaFactory.newSchema(SchemaFactory.java:638)
at Main.validate(Main.java:54)
at Main.main(Main.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
org.xml.sax.SAXParseException; systemId: file:///C:/Users/adobryn/Java/sub/schema.xsd; lineNumber: 456; columnNumber: 73; src-resolve: Cannot resolve the name 'st_Term' to a(n) 'type definition' component.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:134)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:437)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaErr(XSDHandler.java:4162)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaError(XSDHandler.java:4145)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.getGlobalDecl(XSDHandler.java:1741)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDElementTraverser.traverseNamedElement(XSDElementTraverser.java:405)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDElementTraverser.traverseLocal(XSDElementTraverser.java:194)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.traverseLocalElements(XSDHandler.java:3618)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.parseSchema(XSDHandler.java:633)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadSchema(XMLSchemaLoader.java:616)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:574)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:540)
at com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory.newSchema(XMLSchemaFactory.java:255)
at javax.xml.validation.SchemaFactory.newSchema(SchemaFactory.java:638)
at Main.validate(Main.java:54)
at Main.main(Main.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Schema with include:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/schema" targetNamespace="http://www.w3.org/schema" elementFormDefault="qualified">
<xsd:include schemaLocation="st_Term.xsd"/>
<xsd:element name="Term" type="st_Term" minOccurs="0" maxOccurs="1"/>
</xsd:schema>
I think, there is something wrong with getStringData() method. How can I modify it? Thanks for your help!
The problem was, that included xsd also has an include, and ResourceResolver looked in resources folder for it, not resources/sub, where that subincluded xsd was. So, I took another example, that has path tracking, and it works now :) Please note, that schemaBasePath should start with "/"
I had the same problem with includes in .xsd several years ago.
As I can remember my problem was that .xsd resource and its includes were located in some package (directory) within resources.
I've solved it with the following ResourceResolver where the package is passed to constructor (resourceRoot argument):
class ResourceResolver implements LSResourceResolver {
private String resourceRoot;
public ResourceResolver(String resourceRoot) {
this.resourceRoot = resourceRoot;
}
public LSInput resolveResource(String type, String namespaceURI,String publicId, String systemId, String baseURI) {
InputStream resourceAsStream = this.getClass().getResourceAsStream(resourceRoot + "/" + systemId);
return new Input(publicId, systemId, resourceAsStream);
}
}
and Input:
static class Input implements LSInput {
private String publicId;
private String systemId;
public String getPublicId() {
return publicId;
}
public void setPublicId(String publicId) {
this.publicId = publicId;
}
public String getBaseURI() {
return null;
}
public InputStream getByteStream() {
return null;
}
public boolean getCertifiedText() {
return false;
}
public Reader getCharacterStream() {
return null;
}
public String getEncoding() {
return null;
}
public String getStringData() {
synchronized (inputStream) {
try {
byte[] input = new byte[inputStream.available()];
inputStream.read(input);
String contents = new String(input, "UTF-8");
return contents;
} catch (IOException e) {
e.printStackTrace();
System.out.println("Exception " + e);
return null;
}
}
}
public void setBaseURI(String baseURI) {
}
public void setByteStream(InputStream byteStream) {
}
public void setCertifiedText(boolean certifiedText) {
}
public void setCharacterStream(Reader characterStream) {
}
public void setEncoding(String encoding) {
}
public void setStringData(String stringData) {
}
public String getSystemId() {
return systemId;
}
public void setSystemId(String systemId) {
this.systemId = systemId;
}
private final BufferedInputStream inputStream;
public Input(String publicId, String sysId, InputStream input) {
this.publicId = publicId;
this.systemId = sysId;
this.inputStream = new BufferedInputStream(input);
}
}
Related
I want to test a method, which receives a CompletedFileUpload.
public void uploadZip(String orderId, CompletedFileUpload fileUpload) throws IOException {
Path path = Files.createTempFile("file-", "-temp");
File tempFile = path.toFile();
try (FileOutputStream outputStream = new FileOutputStream(tempFile)) {
outputStream.write(fileUpload.getBytes());
someMethod(orderId, tempFile);
}
}
The CompletedFileUpload is an interface:
package io.micronaut.http.multipart;
public interface CompletedFileUpload extends FileUpload, CompletedPart {
}
I want to find a way to Mock the File upload, for spring boot i found :
MockMultipartFile multipartFile =
new MockMultipartFile("springboot.png", "springboot.png", "image/png", "".getBytes());
Is there something similar that I can use in Micronaut?
You can build your own MockFileUpload test class the way Spring does:
public class MockFileUpload implements CompletedFileUpload {
private final String filename;
private final MediaType mediaType;
private final byte[] content;
public MockFileUpload(String filename, MediaType mediaType) {
this(filename, mediaType, null);
}
public MockFileUpload(String filename, MediaType mediaType, #Nullable byte[] content) {
this.filename = filename;
this.mediaType = mediaType;
this.content = (content != null ? content : new byte[0]);
}
#Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(content);
}
#Override
public byte[] getBytes() throws IOException {
return content;
}
#Override
public ByteBuffer getByteBuffer() throws IOException {
return ByteBuffer.wrap(content);
}
#Override
public Optional<MediaType> getContentType() {
return Optional.of(mediaType);
}
#Override
public String getName() {
return filename;
}
#Override
public String getFilename() {
return filename;
}
#Override
public long getSize() {
return content.length;
}
#Override
public long getDefinedSize() {
return content.length;
}
#Override
public boolean isComplete() {
return true;
}
}
and then in your tests you can use the class this way:
CompletedFileUpload file = new MockFileUpload("invoice.pdf", MediaType.APPLICATION_PDF_TYPE);
for several days I have been trying to implement the upload file in Java-GraphQL. I found this topic: How to upload files with graphql-java? I implemented second solutions.
public class FileUpload {
private String contentType;
private byte[] content;
public FileUpload(String contentType, byte[] content) {
this.contentType = contentType;
this.content = content;
}
public String getContentType() {
return contentType;
}
public byte[] getContent() {
return content;
}
}
public class MyScalars {
public static final GraphQLScalarType FileUpload = new GraphQLScalarType(
"FileUpload",
"A file part in a multipart request",
new Coercing<FileUpload, Void>() {
#Override
public Void serialize(Object dataFetcherResult) {
throw new CoercingSerializeException("Upload is an input-only type");
}
#Override
public FileUpload parseValue(Object input) {
if (input instanceof Part) {
Part part = (Part) input;
try {
String contentType = part.getContentType();
byte[] content = new byte[part.getInputStream().available()];
part.delete();
return new FileUpload(contentType, content);
} catch (IOException e) {
throw new CoercingParseValueException("Couldn't read content of the uploaded file");
}
} else if (null == input) {
return null;
} else {
throw new CoercingParseValueException(
"Expected type " + Part.class.getName() + " but was " + input.getClass().getName());
}
}
#Override
public FileUpload parseLiteral(Object input) {
throw new CoercingParseLiteralException(
"Must use variables to specify Upload values");
}
});
}
public class FileUploadResolver implements GraphQLMutationResolver {
public Boolean uploadFile(FileUpload fileUpload) {
String fileContentType = fileUpload.getContentType();
byte[] fileContent = fileUpload.getContent();
// Do something in order to persist the file :)
return true;
}
}
scalar FileUpload
type Mutation {
uploadFile(fileUpload: FileUpload): Boolean
}
I get this error during compilation:
Caused by: com.coxautodev.graphql.tools.SchemaClassScannerError: Expected a user-defined GraphQL scalar type with name 'FileUpload' but found none!
Have you registered it via RuntimeWiring?
Take a look here: Custom Scalar in Graphql-java
You have to extend GraphQLScalarType in your MyScalars class
I am a bit lost at this point. I am by no means a SOAP/JAXb expert, however, I am trying to create a generic class that will marshal/call/unmarshal for any service. I am using the Weather Service wsdl as a starting point to prove out the concept.
I have finally gotten the marshalling, call and unmarshalling to execute without error, however, the response object is not being populated. Can anyone assist in identifying what I am doing incorrectly? I am also looking for a good explanation to the answer if possible so I can learn from this experience.
Again, there is no error while excuting. The issue is that the value of GetCityWeatherByZIPResponse.GetCityWeatherByZIPResult comes out to be null. I know the document is returning the correct results as the result printout is as follows:
Result printout:
<?xml version="1.0" encoding="UTF-8"?><GetCityWeatherByZIPResponse xmlns="http://ws.cdyne.com/WeatherWS/">
<GetCityWeatherByZIPResult>
<Success>true</Success>
<ResponseText>City Found</ResponseText>
<State>MO</State>
<City>Saint Charles</City>
<WeatherStationCity>Farmington</WeatherStationCity>
<WeatherID>4</WeatherID>
<Description>Sunny</Description>
<Temperature>79</Temperature>
<RelativeHumidity>47</RelativeHumidity>
<Wind>CALM</Wind>
<Pressure>30.00S</Pressure>
<Visibility/>
<WindChill/>
<Remarks/>
</GetCityWeatherByZIPResult>
</GetCityWeatherByZIPResponse>
Response: GetCityWeatherByZIPResult: null
Test Web Service:
http://wsf.cdyne.com/WeatherWS/Weather.asmx
Initial call (done via JBehave):
#Given("I call the weather soap service")
public void givenICallTheWeatherSoapService() {
GetCityWeatherByZIP weather = new GetCityWeatherByZIP();
weather.setZIP("63304");
try {
new WeatherTools();
WeatherSoap weatherSoap = new WeatherSoap();
GetCityWeatherByZIPResponse response = weatherSoap.getCityWeatherByZip("63304");
System.out.println("Response: " + response);
} catch (JAXBException | ParserConfigurationException | SOAPException | IOException e) {
Assert.fail(e.getMessage());
}
}
Soap Service Class:
public class WeatherSoap extends PTFSoapClient {
public WeatherSoap() throws JAXBException, ParserConfigurationException, SOAPException {
super(PTFApplication.getConfig(Environment.executionEnv.getEnv(), "Weather SOAP endpoint"));
}
public GetCityWeatherByZIPResponse getCityWeatherByZip(String zip) throws JAXBException, SOAPException, IOException {
GetCityWeatherByZIP weatherByZip = new GetCityWeatherByZIP();
weatherByZip.setZIP(zip);
try {
sendRequest(weatherByZip);
return (GetCityWeatherByZIPResponse) unmarshallResponse(GetCityWeatherByZIPResponse.class);
} catch (ParserConfigurationException | XMLStreamException e) {
e.printStackTrace();
return null;
}
}
}
Base Framework Class genericizing the call (usable for all SOAP calls):
public class PTFSoapClient {
private JAXBContext context;
private Marshaller marshaller;
private Object object;
private SOAPMessage message;
private String endpoint;
private SOAPMessage response;
public PTFSoapClient(String endpoint) {
this.endpoint = endpoint;
}
public void toConsole() throws JAXBException, SOAPException, IOException {
message.writeTo(System.out);
System.out.print("\n");
}
public SOAPMessage sendRequest(Object obj) throws JAXBException, ParserConfigurationException, SOAPException {
object = obj;
context = JAXBContext.newInstance(obj.getClass());
marshaller = context.createMarshaller();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document doc = dbf.newDocumentBuilder().newDocument();
marshaller.marshal(object,doc);
MessageFactory factory = MessageFactory.newInstance();
message = factory.createMessage();
message.getSOAPBody().addDocument(doc);
message.saveChanges();
SOAPConnection connection = SOAPConnectionFactory.newInstance().createConnection();
response = connection.call(message, endpoint);
connection.close();
try {
System.out.println("Response:");
response.writeTo(System.out);
System.out.println("");
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
public Object unmarshallResponse(Class<?> classname) throws JAXBException, XMLStreamException, SOAPException, IOException {
Document doc = response.getSOAPBody().extractContentAsDocument();
try {
System.out.println("Document: ");
printDocument(doc, System.out);
System.out.println("");
} catch (TransformerException e) {
e.printStackTrace();
}
Unmarshaller unmarshaller = JAXBContext.newInstance(classname).createUnmarshaller();
return unmarshaller.unmarshal(doc);
}
public static void printDocument(Document doc, OutputStream out) throws IOException, TransformerException {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
transformer.transform(new DOMSource(doc),
new StreamResult(new OutputStreamWriter(out, "UTF-8")));
}
}
Base unmarshal object:
#XmlRootElement(name = "GetCityWeatherByZIPResponse",
namespace = "http://ws.cdyne.com/WeatherWS/")
public class GetCityWeatherByZIPResponse {
GetCityWeatherByZIPResult GetCityWeatherByZIPResult;
public GetCityWeatherByZIPResult getGetCityWeatherByZIPResult() {
return GetCityWeatherByZIPResult;
}
public void setGetCityWeatherByZIPResult(GetCityWeatherByZIPResult GetCityWeatherByZIPResult) {
this.GetCityWeatherByZIPResult = GetCityWeatherByZIPResult;
}
#Override
public String toString() {
return "GetCityWeatherByZIPResult: " + GetCityWeatherByZIPResult;
}
}
Sub umarshal object:
public class GetCityWeatherByZIPResult {
boolean Success;
String ResponseText;
String State;
String City;
String WeatherStationCity;
String WeatherID;
String Description;
int Temperature;
int RelativeHumidity;
String Wind;
String Pressure;
String Visibility;
String WindChill;
String Remarks;
public boolean isSuccess() {
return Success;
}
public void setSuccess(boolean success) {
Success = success;
}
public String getResponseText() {
return ResponseText;
}
public void setResponseText(String responseText) {
ResponseText = responseText;
}
public String getState() {
return State;
}
public void setState(String state) {
State = state;
}
public String getCity() {
return City;
}
public void setCity(String city) {
City = city;
}
public String getWeatherStationCity() {
return WeatherStationCity;
}
public void setWeatherStationCity(String weatherStationCity) {
WeatherStationCity = weatherStationCity;
}
public String getWeatherID() {
return WeatherID;
}
public void setWeatherID(String weatherID) {
WeatherID = weatherID;
}
public String getDescription() {
return Description;
}
public void setDescription(String description) {
Description = description;
}
public int getTemperature() {
return Temperature;
}
public void setTemperature(int temperature) {
Temperature = temperature;
}
public int getRelativeHumidity() {
return RelativeHumidity;
}
public void setRelativeHumidity(int relativeHumidity) {
RelativeHumidity = relativeHumidity;
}
public String getWind() {
return Wind;
}
public void setWind(String wind) {
Wind = wind;
}
public String getPressure() {
return Pressure;
}
public void setPressure(String pressure) {
Pressure = pressure;
}
public String getVisibility() {
return Visibility;
}
public void setVisibility(String visibility) {
Visibility = visibility;
}
public String getWindChill() {
return WindChill;
}
public void setWindChill(String windChill) {
WindChill = windChill;
}
public String getRemarks() {
return Remarks;
}
public void setRemarks(String remarks) {
Remarks = remarks;
}
}
Your Current Mapping
When you specify the namespace property on the #XmlRootElement annotation, it only applies to that one element.
#XmlRootElement(name = "GetCityWeatherByZIPResponse",
namespace = "http://ws.cdyne.com/WeatherWS/")
public class GetCityWeatherByZIPResponse {
Your XML Document
Your XML document specifies a default namespace. This means that all elements without another explicit namespace mapping are also part of the http://ws.cdyne.com/WeatherWS/ namespace.
<?xml version="1.0" encoding="UTF-8"?><GetCityWeatherByZIPResponse xmlns="http://ws.cdyne.com/WeatherWS/">
<GetCityWeatherByZIPResult>
<Success>true</Success>
The Namespace Fix
You are going to want to specify the namespace mapping at the package level so that it applies to all your element mappings. This is done using the package level #XmlSchema annotation on a speciial class called package-info.
#XmlSchema(
namespace = "http://ws.cdyne.com/WeatherWS/",
elementFormDefault = XmlNsForm.QUALIFIED)
package example;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
For More Information
I have written more about JAXB and namespace qualification on my blog:
http://blog.bdoughan.com/2010/08/jaxb-namespaces.html
Update
Default Element Names
The default elements for your properties don't match your XML. for the property below the expected element name will be getCityWeatherByZIPResult so you will need to override the default using the #XmlElement annotation.
#XmlElement(name="GetCityWeatherByZIPResult")
public GetCityWeatherByZIPResult getGetCityWeatherByZIPResult() {
return GetCityWeatherByZIPResult;
}
Debugging Tip
When you encounter problems unmarshalling, populate your object model and marshal it to see what the expected XML is based on your current mappings.
I'm newbie in XML parsing and try to understand JAXB. Have the following task:
Implemented the following method, to got the személy object by id parameter,but it returns null:
public Személy getSzemélyById(String id) {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(Személy.class);
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
XMLReader xmlReader = spf.newSAXParser().getXMLReader();
InputSource inputSource;
inputSource = new InputSource(new FileReader("C:\\Users\\zbocskay.TS-EU\\Documents\\NetBeansProjects\\prt2014levzh\\people.xml"));
SAXSource source = new SAXSource(xmlReader, inputSource);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Személy személy = (Személy) unmarshaller.unmarshal(source);
System.out.println(személy.toString());
return new Személy(személy.getId(), személy.getVezetéknév(), személy.getKeresztnév(), személy.getÉletkor(), személy.getCím(), személy.státusz.DIÁK);
} catch (JAXBException e) {
} catch (FileNotFoundException | ParserConfigurationException ex) {
Logger.getLogger(SzemélyDAOImpl.class.getName()).log(Level.SEVERE, null, ex);
} catch (SAXNotRecognizedException ex) {
Logger.getLogger(SzemélyDAOImpl.class.getName()).log(Level.SEVERE, null, ex);
} catch (SAXNotSupportedException ex) {
Logger.getLogger(SzemélyDAOImpl.class.getName()).log(Level.SEVERE, null, ex);
} catch (SAXException ex) {
Logger.getLogger(SzemélyDAOImpl.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
Here is Személy Class:
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Személy {
public enum Státusz {
FELNŐTT, DIÁK, NYUGDÍJAS, GYERMEK
}
#XmlElement
protected String id;
#XmlElement
protected String vezetéknév;
#XmlElement
protected String keresztnév;
protected Integer életkor;
#XmlElement
protected String cím;
protected Státusz státusz;
public Személy(String id) {
super();
this.id = id;
}
public void setÉletkor(Integer életkor) {
this.életkor = életkor;
}
public String getVezetéknév() {
return vezetéknév;
}
public void setVezetéknév(String vezetéknév) {
this.vezetéknév = vezetéknév;
}
public String getKeresztnév() {
return keresztnév;
}
public void setKeresztnév(String keresztnév) {
this.keresztnév = keresztnév;
}
public String getCím() {
return cím;
}
public void setCím(String cím) {
this.cím = cím;
}
public String getId() {
return id;
}
public Személy(String id, String vezetéknév, String keresztnév,
Integer életkor, String cím, Státusz státusz) {
this(id);
this.vezetéknév = vezetéknév;
this.keresztnév = keresztnév;
this.életkor = életkor;
this.cím = cím;
this.státusz = státusz;
}
public Személy(String id, String vezetéknév, String keresztnév,
String születésiDátum, String cím, String diákigazolványszám,
Státusz státusz) throws ParseException {
this(id);
this.vezetéknév = vezetéknév;
this.keresztnév = keresztnév;
this.életkor = meghatározÉletkort(születésiDátum);
this.cím = cím;
this.státusz = státusz;
}
public Integer getÉletkor() {
return életkor;
}
#Override
public String toString() {
return "Személy [id=" + id + ", vezetéknév=" + vezetéknév
+ ", keresztnév=" + keresztnév + ", életkor=" + életkor
+ ", cím=" + cím + ", státusz=" + státusz + "]";
}
}
And people.xml file with data:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE személyek SYSTEM "people.dtd">
<személyek>
<személy id="micimacko">
<vezetéknév>Mici</vezetéknév>
<keresztnév>Mackó</keresztnév>
<születésidátum>1921.08.21</születésidátum>
<cím>Százholdas Pagony</cím>
<fotó>http://upload.wikimedia.org/wikipedia/en/1/10/Winniethepooh.png
</fotó>
</személy>
</személyek>
Running in the main class by the following:
public static void main(String args[]) {
SzemélyDAO ddd = new SzemélyDAOImpl();
System.out.println(ddd.getSzemélyById("micimacko"));
}
Could anybody help me, what am I doing wrong?Thanks.
As the exception states you need to add a no-arg constructor to your Személy class. This means a constructor that doesn't take any parameters. Currently the class has a single constructor that takes a String. Adding the following would work:
private Személy() {
}
I'm attempting to following this example of SAX XML Parser: How to parse XML using the SAX parser
However when debugging - some items are returning null. I have verified they are contained within the XML file I am connecting to - but I believe I've set my getVideos/setVideos parameters incorrectly and I'm not sure how they might be corrected.
XML Data
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<response>
<cmd>getVideos</cmd>
<success>1</success>
<NumberOfVideos>4</NumberOfVideos>
<Videos>
<Video>
<VideoName>sample_iPod</VideoName>
<VideoDesc/>
<VideoUrl>
http://mobile.example.com/omv/wp-content/uploads/sites/6/2014/01/omv/1/06087297988b.m4v
</VideoUrl>
<VideoTags/>
</Video>
<Video>
<VideoName>sample_mpeg4</VideoName>
<VideoDesc/>
<VideoUrl>
http://mobile.example.com/omv/wp-content/uploads/sites/6/2014/01/omv/1/b5ed9e7100e2.mp4
</VideoUrl>
<VideoTags/>
</Video>
<Video>
<VideoName>sample_sorenson</VideoName>
<VideoDesc/>
<VideoUrl>
http://mobile.example.com/omv/wp-content/uploads/sites/6/2014/01/omv/1/2a8e64b24997.mov
</VideoUrl>
<VideoTags/>
</Video>
<Video>
<VideoName>sample_iTunes</VideoName>
<VideoDesc/>
<VideoUrl>
http://mobile.example.com/omv/wp-content/uploads/sites/6/2014/01/omv/1/6c7f65254aad.mov
</VideoUrl>
<VideoTags/>
</Video>
</Videos>
</response>
SAX Parser Related Java:
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (qName.equalsIgnoreCase("response")) {
// add it to the list
response.add(cmd);
} else if (qName.equalsIgnoreCase("success")) {
cmd.setSuccess(tempVal);
} else if (qName.equalsIgnoreCase("numberofvideos")) {
cmd.setNumberOfVideos(tempVal);
} else if (qName.equalsIgnoreCase("videos")) {
cmd.setVideos(tempVal);
} else if (qName.equalsIgnoreCase("video")) {
cmd.setVideo(tempVal);
} else if (qName.equalsIgnoreCase("videoname")) {
cmd.setVideoName(tempVal);
} else if (qName.equalsIgnoreCase("videourl")) {
cmd.setVideoURL(tempVal);
}
...
public class SAXXMLParser {
public static List<Cmd> parse(InputStream is) {
List<Cmd> response = null;
try {
// create a XMLReader from SAXParser
XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser()
.getXMLReader();
// create a SAXXMLHandler
SAXXMLHandler saxHandler = new SAXXMLHandler();
// store handler in XMLReader
xmlReader.setContentHandler(saxHandler);
// the process starts
xmlReader.parse(new InputSource(is));
// get the `Video list`
response = saxHandler.getResponse();
} catch (Exception ex) {
Log.d("XML", "SAXXMLParser: parse() failed");
ex.printStackTrace();
}
// return Laptop list
return response;
}
}
...
public class Cmd {
private String success;
private String cmd;
private String videos;
private String video;
private String numberofvideos;
private String videoname;
private String videourl;
public String getCmd() {
return cmd;
}
public void setCmd(String cmd) {
this.cmd = cmd;
}
public String getSuccess() {
return success;
}
public void setSuccess(String success) {
this.success = success;
}
public String getNumberOfVideos() {
return numberofvideos;
}
public void setNumberOfVideos(String numberofvideos) {
this.numberofvideos = numberofvideos;
}
public String getVideos() {
return videos;
}
public void setVideos(String videos) {
this.videos = videos;
}
public String getVideo() {
return video;
}
public void setVideo(String video) {
this.video = video;
}
public String getVideoName() {
return videoname;
}
public void setVideoName(String videoname) {
this.videoname = videoname;
}
public String getVideoURL() {
return videourl;
}
public void setVideoURL(String videourl) {
this.video = videourl;
}
Please let me know if any additional information is required. I will be happy to provide it.
Your code sets the member video instead of videourl in setvideourl method
public void setVideoURL(String videourl) {
this.video = videourl;<<----
This.videourl = videourl;
}