I convert element xml to object with this code:
public static Object xmlToObject(Element element, Class c, org.apache.logging.log4j.Logger log) {
try {
if (log != null) {
log.debug(element);
log.debug("este es el resultado ");
}
JDOMSource source = new JDOMSource(element);
JAXBContext context = JAXBContext.newInstance(c);
Unmarshaller un = context.createUnmarshaller();
return un.unmarshal(source);
} catch (JAXBException ex) {
java.util.logging.Logger.getLogger(SiodexClient.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
in weblogic 10 works and console java normal execution too, but in weblogic 12 dont works why?
this is error:
[Exception [EclipseLink-25008] (Eclipse Persistence Services - 2.6.5.v20170607-b3d05bd): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: A descriptor with default root element cod_tipo_operacion was not found in the project]
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.handleXMLMarshalException(JAXBUnmarshaller.java:1110)
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:335)
at mefp.itg.clws.bcb.siodex.SiodexClient.xmlToObject(SiodexClient.java:216)
help please
Related
I'm try to validate an XML using StAX and javax Validator however I'm getting the following cast error:
org.xml.sax.SAXException: java.lang.ClassCastException: org.codehaus.stax2.ri.evt.NamespaceEventImpl cannot be cast to java.lang.String
javax.xml.transform.TransformerException: java.lang.ClassCastException: org.codehaus.stax2.ri.evt.NamespaceEventImpl cannot be cast to java.lang.String
The basic idea is that I need to parse an XML using StAX and I'm attempting to reuse the event reader I'll be using for parsing and creating a StAXSource to perform the validation.
I was able to debug the error and trace the cast exception to the class com.sun.org.apache.xalan.internal.xsltc.trax.StAXEvent2SAX, line 341, where there is a loop through an iterator and a cast to a String when in fact the iterator has the type NamespaceEventImpl (snippet code of the portion of code below).
// end namespace bindings
for( Iterator i = event.getNamespaces(); i.hasNext();) {
String prefix = (String)i.next();
if( prefix == null ) { // true for default namespace
prefix = "";
}
_sax.endPrefixMapping(prefix);
}
The following is the content of the iterator "i" while performing the logic I'm referring to:
iterator content
Below is a snippet of code describing how I'm doing it.
public void validateRequest(RequestMessage message) {
try {
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLEventReader eventReader = factory.createXMLEventReader(new ByteArrayInputStream(message.getMessage().getBytes()));
this.validateSchema(eventReader);
if(this.isSchemaValid()) {
// parse through XML
}
} catch(Exception e) {
LOGGER.error(e.getMessage(), e);
}
}
private void validateSchema(XMLEventReader eventReader) {
try {
StAXErrorHandler errorHandler = new StAXErrorHandler();
this.validator.setErrorHandler(errorHandler);
this.validator.validate(new StAXSource(eventReader));
} catch (SAXException | IOException | XMLStreamException e) {
LOGGER.error(e.getMessage(), e);
}
}
I was wondering if someone faced this issue before and if it is a limitation of using StAXSource with the Validator itself.
I am trying to get the lists present on a sharepoint site using SP webservice.
Lists listsSevice = new Lists(new URL(spSiteURL + "/_vti_bin/Lists.asmx?wsdl"));
listsSevice.setHandlerResolver(new SPHandlerResolver());
spListsServiceIfx = listsSevice.getListsSoap();
// Calling the List Web Service
GetListItemsResponse.GetListItemsResult result = spListsServiceIfx .getListItems(listName, viewName, query, viewFields, rowLimit, queryOptions, webID);
However, I get this error because of some invalid character present in soap response.
com.sun.xml.ws.encoding.soap.DeserializationException: Failed to read a response: javax.xml.bind.UnmarshalException
- with linked exception:
[com.ctc.wstx.exc.WstxParsingException: Illegal character entity: expansion character (code 0x15 at [row,col {unknown-source}]: [1125,122]]
I tried to modify the SOAPMessage to remove invalid characters from response.
public class SOAPMessageHandler implements SOAPHandler<SOAPMessageContext> {
public boolean handleMessage(SOAPMessageContext smc) {
System.out.println("in handleMessage");
Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
System.out.println("outboundProperty: " + outboundProperty);
try {
if (outboundProperty.booleanValue()) {
System.out.println(" SOAP Request ");
} else {
System.out.println(" SOAP Response ");
SOAPMessage message = smc.getMessage();
message.writeTo(System.out);
ByteArrayOutputStream out = new ByteArrayOutputStream();
message.writeTo(out);
String messageAsString = new String(out.toByteArray());
/*smc.setMessage(new SOAPMessage(
stripNonValidXMLCharacters(message.getSOAPPart().toString())));*/
}
} catch (SOAPException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
System.out.println("in soap msg handler..." + e.getMessage());
e.printStackTrace();
}
System.out.println("");
return true;
}
But I get an exception at
SOAPMessage message = smc.getMessage();
The stack trace is:
javax.xml.ws.WebServiceException: javax.xml.soap.SOAPException: org.xml.sax.SAXParseException; lineNumber: 1125; columnNumber: 122; Illegal character entity: expansion character (code 0x15
at [row,col {unknown-source}]: [1125,122]
at com.sun.xml.ws.handler.SOAPMessageContextImpl.getMessage(SOAPMessageContextImpl.java:86)
at com.cah.ecm.sharepoint.migrator.util.SOAPMessageHandler.handleMessage(SOAPMessageHandler.java:25)
at com.cah.ecm.sharepoint.migrator.util.SOAPMessageHandler.handleMessage(SOAPMessageHandler.java:1)
at com.sun.xml.ws.handler.HandlerProcessor.callHandleMessageReverse(HandlerProcessor.java:341)
at com.sun.xml.ws.handler.HandlerProcessor.callHandlersResponse(HandlerProcessor.java:214)
at com.sun.xml.ws.handler.ClientSOAPHandlerTube.callHandlersOnResponse(ClientSOAPHandlerTube.java:163)
at com.sun.xml.ws.handler.HandlerTube.processResponse(HandlerTube.java:164)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:651)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:600)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:585)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:482)
at com.sun.xml.ws.client.Stub.process(Stub.java:323)
at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:161)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:113)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:93)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:144)
at com.sun.proxy.$Proxy28.getListItems(Unknown Source)
at com.cah.ecm.sharepoint.migrator.sharepoint.client.SharepointClient.getListItemNodes(SharepointClient.java:292)
at com.cah.ecm.sharepoint.migrator.sharepoint.client.SharepointClient.getListItems(SharepointClient.java:389)
at com.cah.ecm.sp.jde.main.TestIterateAllSPFiles.main(TestIterateAllSPFiles.java:35)
Please help me with where I am wrong and if there is an alternate way to remove invalid characters from SOAP response.
Thanks!
One option is to implement your own SAAJMetaFactory that will create custom MessageFactory. Like this:
import java.io.IOException;
import java.io.InputStream;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import com.sun.xml.internal.messaging.saaj.soap.SAAJMetaFactoryImpl;
public class OwnSAAJMetaFactoryImpl extends SAAJMetaFactoryImpl {
#Override
protected MessageFactory newMessageFactory(String protocol) throws SOAPException {
final MessageFactory f = super.newMessageFactory(protocol);
return new MessageFactory() {
#Override
public SOAPMessage createMessage(MimeHeaders headers, InputStream in) throws IOException, SOAPException {
in = doCleaingStuff(in);
return createMessage(headers, in);
}
#Override
public SOAPMessage createMessage() throws SOAPException {
return f.createMessage();
}
};
}
private InputStream doCleaingStuff(InputStream in) {
// TODO implement it
return null;
}
}
According to SAAJMetaFactory#getInstance() documentation your OwnSAAJMetaFactoryImpl can be exposed through system property
System.setProperty("javax.xml.soap.MetaFactory", "own.package.OwnSAAJMetaFactoryImpl");
or any of this way
Use the javax.xml.soap.MetaFactory system property.
Use the properties file "lib/jaxm.properties" in the JRE directory. This configuration file is in standard java.util.Properties format and
contains the fully qualified name of the implementation class with the
key being the system property defined above.
Use the Services API (as detailed in the JAR specification), if available, to determine the classname. The Services API will look for
a classname in the file META-INF/services/javax.xml.soap.MetaFactory
in jars available to the runtime.
Default to com.sun.xml.messaging.saaj.soap.SAAJMetaFactoryImpl.
I want to validate a xml file with its xsd before unmarshalling it.
The code is as follows :
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = factory.newSchema(xsdFilePath);
Validator validator = schema.newValidator();
validator.setErrorHandler(new MyValidationErrorHandler());
validator.validate(new StreamSource(xmlFilePath));
I found that when a xml element is not closed, Validator failed to record it as an error, But the UnMarshaller recognizes this and throws an "Invalid content was found starting with element.." Error.
I want the Validation and the Unmarshalling/Marshalling to be different operations.
Are there ways to have the Validator detect such syntax errors in the xml file?
You'll have to distinguish two things:
The elementary syntax of an XML document
The document's compliance with an XML SChema
If the elementary syntax isn't right, there's no document that can be investigated for its element structure, attribure existence, value compliance with facets and so on and so on.
I'm afraid you'll have to catch both kinds of exceptions.
You may, however, handle everything in a single unmarshalling operation:
JAXBContext payloadContext = JAXBContext.newInstance("generated");
Unmarshaller unmarshaller = payloadContext.createUnmarshaller();
unmarshaller.setSchema(schemaFactory.newSchema(... )););
unmarshaller.setEventHandler( new ValidationEventHandler(){
public boolean handleEvent(ValidationEvent event) {
System.out.println( "Event! " + event );
return true;
}
} );
Later
To have validation only, you'll still have to parse, but if you don't have JAXB-ish classes, you get by with JAXP:
static class Handler implements ErrorHandler {
public void error(SAXParseException exception){
System.out.println( "error: " + exception.getMessage() );
}
public void fatalError(SAXParseException exception){
System.out.println( "fatal: " + exception.getMessage() );
}
public void warning(SAXParseException exception){
System.out.println( "warning: " + exception.getMessage() );
}
}
Handler handler = new Handler();
DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
parser.setErrorHandler( handler );
try {
Document document = parser.parse(new File("test.xml"));
SchemaFactory factory =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Source schemaFile = new StreamSource(new File("test.xsd"));
Schema schema = factory.newSchema(schemaFile);
Validator validator = schema.newValidator();
validator.setErrorHandler( handler );
try {
validator.validate(new DOMSource(document));
} catch (SAXException e) {
// ...
System.out.println( "VAlidation error" );
}
} catch (SAXParseException e) {
// syntax error in XML document
System.out.println( "Syntax error" );
}
For validation, setting a handler will not throw a ParseException, so one of these is redundant.
I'm trying to parse a GPX file using JAXBU here is my code:
GpxType unmarshal(String path) {
GpxType list = new GpxType();
try {
javax.xml.bind.JAXBContext jaxbCtx = javax.xml.bind.JAXBContext
.newInstance(list.getClass().getPackage().getName());
javax.xml.bind.Unmarshaller unmarshaller = jaxbCtx.createUnmarshaller();
list = (GpxType) unmarshaller.unmarshal(new java.io.File(path)); //NOI18N
return list;
} catch (javax.xml.bind.JAXBException ex) {
// XXXTODO Handle exception
java.util.logging.Logger.getLogger("global")
.log(java.util.logging.Level.SEVERE, null, ex); //NOI18N
}
return null;
}
however i get the following error:
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException:
javax.xml.bind.JAXBElement cannot be cast to GPXfiles.GpxType
so im guessing its because using JAXBU its looking for a XML file instead of a GPX file. Any help would be appreciated :)
You can call JAXBIntrospector.getValue(Object) on the result of the unmarshal operation to guard against the result being wrapped in a JAXBElement.
I am validating an in-memory DOM object using the javax.xml.validation.Validator class against an XSD schema. I am getting a SAXParseException being thrown during the validation whenever there is some data corruption in the information I populate my DOM from.
An example error:
org.xml.SAXParseException: cvc-datatype-valid.1.2.1: '???"??[?????G?>???p~tn??~0?1]' is not a valid valud for 'hexBinary'.
What I am hoping is that there is a way to find the location of this error in my in-memory DOM and print out the offending element and its parent element. My current code is:
public void writeDocumentToFile(Document document) throws XMLWriteException {
try {
// Validate the document against the schema
Validator validator = getSchema(xmlSchema).newValidator();
validator.validate(new DOMSource(document));
// Serialisation logic here.
} catch(SAXException e) {
throw new XMLWriteException(e); // This is being thrown
} // Some other exceptions caught here.
}
private Schema getSchema(URL schema) throws SAXException {
SchemaFactory schemaFactory =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
// Some logic here to specify a ResourceResolver
return schemaFactory.newSchema(schema);
}
I have looked into the Validator#setErrorHandler(ErrorHandler handler) method but the ErrorHandler interface only gives me exposure to a SAXParseException which only exposes the line number and column number of the error. Because I am using an in-memory DOM this returns -1 for both line and column number.
Is there a better way to do this? I don't really want to have to manually validate the Strings before I add them to the DOM if the libraries provide me the function I'm looking for.
I'm using JDK 6 update 26 and JDK 6 update 7 depending on where this code is running.
EDIT: With this code added -
validator.setErrorHandler(new ErrorHandler() {
#Override
public void warning(SAXParseException exception) throws SAXException {
printException(exception);
throw exception;
}
#Override
public void error(SAXParseException exception) throws SAXException {
printException(exception);
throw exception;
}
#Override
public void fatalError(SAXParseException exception) throws SAXException {
printException(exception);
throw exception;
}
private void printException(SAXParseException exception) {
System.out.println("exception.getPublicId() = " + exception.getPublicId());
System.out.println("exception.getSystemId() = " + exception.getSystemId());
System.out.println("exception.getColumnNumber() = " + exception.getColumnNumber());
System.out.println("exception.getLineNumber() = " + exception.getLineNumber());
}
});
I get the output:
exception.getPublicId() = null
exception.getSystemId() = null
exception.getColumnNumber() = -1
exception.getLineNumber() = -1
If you are using Xerces (the Sun JDK default), you can get the element that failed validation through the http://apache.org/xml/properties/dom/current-element-node property:
...
catch (SAXParseException e)
{
Element curElement = (Element)validator.getProperty("http://apache.org/xml/properties/dom/current-element-node");
System.out.println("Validation error: " + e.getMessage());
System.out.println("Element: " + curElement);
}
Example:
String xml = "<root xmlns=\"http://www.myschema.org\">\n" +
"<text>This is text</text>\n" +
"<number>32</number>\n" +
"<number>abc</number>\n" +
"</root>";
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document doc = dbf.newDocumentBuilder().parse(new ByteArrayInputStream(xml.getBytes("UTF-8")));
Schema schema = getSchema(getClass().getResource("myschema.xsd"));
Validator validator = schema.newValidator();
try
{
validator.validate(new DOMSource(doc));
}
catch (SAXParseException e)
{
Element curElement = (Element)validator.getProperty("http://apache.org/xml/properties/dom/current-element-node");
System.out.println("Validation error: " + e.getMessage());
System.out.println(curElement.getLocalName() + ": " + curElement.getTextContent());
//Use curElement.getParentNode() or whatever you need here
}
If you need to get line/column numbers from the DOM, this answer has a solution to that problem.
SaxParseException exposes the SystemId and PublicId. Does that not give you enough information?