Parsing the CreditOrgInfo web service involves retrieving information about credit organizations.

Working with XML data is a common task, and finding efficient solutions is crucial for developers. In this article, we explore the use of the JAXB XML Parser, focusing on manual class description and auto generation of classes. We delve into the challenges of generating classes from the CreditOrgInfo WSDL and propose alternative approaches to overcome these issues.

There is a website that offers a SOAP web service with a database containing information about credit organizations.

Task: Utilize the SOAP service to retrieve information about the Bank Identification Codes (BIC) of all banks in Russia. Parse the XML data and save it to the database.

Used:

Spring jdbc PostgreSQL SOAPConnection
XPath SOAP XML

The web service, CreditOrgInfo, is accessible via the following WSDL: [CreditOrgInfo WSDL]. This service offers various methods, and for our task, we will focus on the EnumBIC_XML method. This method requires an empty message as input.

The EnumBIC_XML method of the CreditOrgInfo web service returns XML as output:

There are multiple approaches to solve this problem. One common approach is to generate classes based on the published WSDL using the utility “wsimport“. This utility can be used to generate the necessary client classes, and Spring can be used to interact with the web service and retrieve the response.

However, you may encounter an error similar to the one mentioned on Stack Overflow: “undefined element declaration ‘s:schema’ line 55”. This error usually occurs when there is an issue with the XML schema definition in the WSDL file.

I see. In that case, the issue might be related to the auto-generated CreditOrgInfo.asmx file, which includes an undefined element. This can happen when the WSDL is not properly generated or when there are discrepancies between the WSDL and the actual implementation.

I understand the challenges you’re facing with generating classes using wsimport due to the undefined element and the large number of methods in the service. It can indeed result in a project with many unused classes and difficulties in finding the necessary ones.

To work around these issues, you’ve identified two potential solutions. The first is to use parameterization via customization.xjb, which you will provide settings for in your GIT project. This approach allows for more control over the generation process and can help address the problem of unused classes.

The second solution involves downloading the WSDL locally, editing it to remove the undefined element, and then generating the classes. While this can help resolve the issue with the undefined element, it still requires manually describing JAXB classes for parsing and data retrieval, especially if the XML contains multiple namespaces. This can be a time-consuming task.

By considering these alternative approaches and taking into account the limitations and challenges of generating classes, you can find the best strategy for effectively parsing and retrieving the necessary data from the CreditOrgInfo web service.

So, the chosen method involves sending a SOAP message using the SOAPConnectionFactory and MessageFactory package. The XML response is then parsed using XPath, converted into a Map, and saved to a PostgreSQL database. This approach allows us to accomplish the task without any unnecessary complexity.

Before proceeding, it is necessary to create a table in the PostgreSQL database, which can be done using the command line as described in the provided resource.

CREATE TABLE bicList(
  id serial PRIMARY KEY,
bic VARCHAR (50) UNIQUE NOT NULL,
rc VARCHAR (50) NOT NULL,
nm VARCHAR (50) NOT NULL,
rb VARCHAR (50) NOT NULL,
rn VARCHAR (50) NOT NULL,
intCode VARCHAR (50) NOT NULL
);

Next, we create a message:

public static void main(String args[]) {
        String soapEndpointUrl = "http://www.cbr.ru/CreditInfoWebServ/CreditOrgInfo.asmx";
        String soapAction = "http://web.cbr.ru/EnumBIC_XML";
        callSoapWebService(soapEndpointUrl, soapAction);
    }
 
    private static void createSoapEnvelope(SOAPMessage soapMessage) throws SOAPException {
        SOAPPart soapPart = soapMessage.getSOAPPart();
 
        String myNamespace = "s";
        String myNamespaceURI = "http://www.cbr.ru/";
 
        // SOAP Envelope
        SOAPEnvelope envelope = soapPart.getEnvelope();
        envelope.addNamespaceDeclaration(myNamespace, myNamespaceURI);
    }
 
private static SOAPMessage createSOAPRequest(String soapAction) throws Exception {
	MessageFactory messageFactory = MessageFactory.newInstance();
	SOAPMessage soapMessage = messageFactory.createMessage();
 
	createSoapEnvelope(soapMessage);
 
	MimeHeaders headers = soapMessage.getMimeHeaders();
	headers.addHeader("SOAPAction", soapAction);
 
	soapMessage.saveChanges();
	return soapMessage;
}

XPATH is used to traverse through the XML structure and extract specific data. It provides a powerful and flexible way to navigate XML documents:

DocumentBuilderFactory dbf =
DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xmlString));
 
Document doc = db.parse(is);
 
// Create XPathFactory object
XPathFactory xpathFactory = XPathFactory.newInstance();
 
// Create XPath object
XPath xpath = xpathFactory.newXPath();
 
int i;
for (i = 1; i < 832; i++) {
XPathExpression expr =
	xpath.compile("//*[local-name()='BIC'][" + i + "]" + "//*[local-name()='BIC'][\" +i+ \"]");
String nodes = (String) expr.evaluate(doc, XPathConstants.STRING);

Once you have extracted the necessary data from the XML using XPATH, you can store it in a Map data structure for further processing or storage. The Map allows you to associate a key with a value, which can be useful for organizing and manipulating the extracted data.

To write the data from the Map to a database, such as PostgreSQL, you can use a database connection library like JDBC (Java Database Connectivity). JDBC provides a set of APIs that enable Java applications to interact with databases.

// Creating map with all required params
Map<string, object=""> paramMap = new HashMap<string, object="">();
paramMap.put("id", i);
paramMap.put("bic", nodes);
paramMap.put("rc", nodes2);
paramMap.put("nm", nodes3);
paramMap.put("rb", nodes4);
paramMap.put("rn", nodes5);
paramMap.put("intcode", nodes6);
 
// Passing map containing named params
nqu.update(INSERT_QUERY, paramMap);
</string,></string,>

To address the challenges with class generation, we present a method that involves sending SOAP messages, parsing XML using XPath, and storing the extracted data in a PostgreSQL database. By bypassing the complexities of class generation, we can efficiently retrieve and save information from the CreditOrgInfo SOAP service. I provide code snippets and instructions for setting up the database, enabling readers to implement this approach in their projects.

Link to the full version of the project on GitHub:
Github CreditOrgInfoProject

Related Posts