7 XML Programming Techniques

This chapter describes specific XML programming techniques for developing a Jakarta EE application with WebLogic Server that processes XML data.

This chapter includes the following sections:

Transmitting XML Data Between a Java Client and WebLogic Server

In a typical Jakarta EE application, a client application sends XML data to a servlet or a JSP that processes the XML data. The servlet or JSP then either sends the data on to another Jakarta EE component, such as a JMS destination or an EJB, or sends the processed XML data back to the client in the form of another XML document.

To send XML data from a Java client to a WebLogic Server-hosted servlet or JSP and read the response, use java.net.http.HttpClient. The following example sends the complete XML file using HTTP POST and reads the response as bytes.

The following Java client program from the WebLogic XML examples shows how to transmit XML data between the program and a JSP:

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Path;
import java.time.Duration;

public final class Client {
    public static void main(String[] args) throws Exception {
        if (args.length != 2) {
            System.err.println("Usage: java Client <URL> <XML-file>");
            return;
        }
        HttpClient client = HttpClient.newBuilder()
            .connectTimeout(Duration.ofSeconds(10))
            .build();
        HttpRequest request = HttpRequest.newBuilder(URI.create(args[0]))
            .timeout(Duration.ofSeconds(30))
            .header("Content-Type", "application/xml")
            .header("Accept", "application/xml")
            .POST(HttpRequest.BodyPublishers.ofFile(Path.of(args[1])))
            .build();
        HttpResponse<byte[]> response = client.send(
            request, HttpResponse.BodyHandlers.ofByteArray());
        if (response.statusCode() < 200 || response.statusCode() >= 300) {
            throw new IOException("HTTP " + response.statusCode());
        }
        System.out.write(response.body());
    }
}

The example posts the XML file given in the argument list, checks the HTTP status, and writes the response bytes without decoding or truncating them. In production, use HTTPS and the application’s required authentication.

The following code segments from a sample JSP show how the JSP receives XML data from the client application, parses the XML document, and sends XML data back:

<%@ page import="java.io.PrintWriter,javax.xml.XMLConstants,javax.xml.parsers.DocumentBuilder,javax.xml.parsers.DocumentBuilderFactory,org.w3c.dom.Document" %>
<%
response.setContentType("application/xml");
response.setCharacterEncoding("UTF-8");
DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance();
fact.setNamespaceAware(true);
fact.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
fact.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
fact.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
fact.setXIncludeAware(false);
fact.setExpandEntityReferences(false);
DocumentBuilder db = fact.newDocumentBuilder();
Document doc = db.parse(request.getInputStream());
// Keep the existing processing that uses doc here.
PrintWriter responseWriter = response.getWriter();
responseWriter.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
%>

Apply an application/container request-size limit. If this endpoint intentionally accepts a controlled trusted DTD or schema, use an allowlisting resolver or catalog instead of opening arbitrary external access.

For detailed information on programming WebLogic servlets and JSPs, see Developing Web Applications, Servlets, and JSPs for Oracle WebLogic Server.

Handling XML Documents in a JMS Application

WebLogic Server provides the following extensions to some Jakarta Messaging (JMS) classes to handle XML documents in a JMS application:

  • weblogic.jms.extensions.WLSession, which extends the JMS class jakarta.jms.Session

  • weblogic.jms.extensions.WLQueueSession, which extends the JMS class jakarta.jms.QueueSession

  • weblogic.jms.extensions.WLTopicSession, which extends the JMS class jakarta.jms.TopicSession

  • weblogic.jms.extensions.XMLMessage, which extends the JMS class jakarta.jms.TextMessage

Use the WebLogic JMS_BEA_SELECT selector function to evaluate XPath against an XMLMessage. For example: JMS_BEA_SELECT('xpath', '/Order/Manifest/Item[2]/ID/text()') = '208'. The first argument selects XPath evaluation, the second is the XPath expression, and the selector compares the returned value.

To create a WebLogic XMLMessage, obtain the provider session as weblogic.jms.extensions.WLSession and call createXMLMessage(). WLQueueSession and WLTopicSession are domain-specific compatibility interfaces that extend WLSession.

For detailed information on using XMLMessage objects in your JMS application, see Developing JMS Applications for Oracle WebLogic Server.

Accessing External Entities That Do Not Have an HTTP Interface

WebLogic Server can retrieve and cache external entities that reside in external repositories, as long as they have an HTTP interface, such as a URL, that returns the entity. See External Entity Configuration Tasks for detailed information on using the XML Registry to configure external entities.

If you want to access an external entity that is stored in a repository that does not have an HTTP interface, you must create an interface. For example, assume you store the DTDs for your XML documents in a database table, with columns for the system id, public id, and text of the DTD. To access the DTD as an external entity from a WebLogic XML application, you could create a servlet that uses JDBC to access the DTDs in the database.

Because you invoke servlets with URLs, you now have an HTTP interface to the external entity. When you create the entity registry entry in the XML Registry, you specify the URL that invokes the servlet as the location of the external entity. When WebLogic Server is parsing an XML document that contains a reference to this external entity, it invokes the servlet, passing it the public and system id, which the servlet can internally use to query the database.