Ağu
28
2015

Weblogic Web Servis Talebi Schema Validasyonu

Merhaba,

Bu yazımda weblogic makinasından servis edilen örnek bir web servis fonksiyonuna ait servis talebinin schema kontrolünden ne şekilde geçirileceğini örnek bir kod ile anlatmaya çalışacağım.

Bu kontrol web servisi için hazırlanan handler class ı içerisinde yapılmaktadır. Schema validasyonu hata ile tamamlandığında handler içerisinden WebServisException fırlatılarak client call işlemi kesilir. Burda web servisi fonksiyonunun kullandığı talebin veri tiplerinin kontrol edilmesinin sağlanması ve Opsiyonel olan alanlar dışında mutlaka kullanılması gereken alanların olması gerektiği yapı ile kullanıldığının kontrolü amaçlanmaktadır.
Eğer ki talep xml li schema validasyonundan geçirilmezse yapıya uygun olmayan veri tipleri örneğin integer bir alana alfanumerik bir değer geldiğinde o alanı 0 olarak set edecektir. Bu durumların önüne geçmek için bu validasyon yapılmalıdır.

Aşağıda örnek olarak ide tarafından generete edilmiş schema görülmektedir. (Calc_schema1.xsd)

Aşağıda kodu verilen SchemaValidate sınıfı içerisinden xsd schemasının doğrudan okunması için web servisin yayın yapıldı domainnin home dizinine konulmalıdır ! Schema file olarak değil doğrudan URL üzerinden de okunabilir.

örnek olarak domain home ” /data01/WLS/Oracle/Middleware/user_projects/domains/base_domain ”

 
 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" targetNamespace="http://xx/" xmlns:tns="http://xx/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
 
  <xs:element name="GenericSoapFault" TYPE="tns:GenericSoapFault"/>
 
  <xs:element name="Karesi" TYPE="tns:Karesi"/>
 
  <xs:element name="KaresiResponse" TYPE="tns:KaresiResponse"/>
 
  <xs:element name="hello" TYPE="tns:hello"/>
 
  <xs:element name="helloResponse" TYPE="tns:helloResponse"/>
 
  <xs:complexType name="Karesi">
    <xs:sequence>
      <xs:element name="sayi" TYPE="xs:int"/>
    </xs:sequence>
  </xs:complexType>
 
  <xs:complexType name="KaresiResponse">
    <xs:sequence>
      <xs:element name="return" TYPE="xs:int"/>
    </xs:sequence>
  </xs:complexType>
 
  <xs:complexType name="GenericSoapFault">
    <xs:sequence>
      <xs:element name="faultInfo" TYPE="tns:soapFault" minOccurs="0"/>
      <xs:element name="message" TYPE="xs:string" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
 
  <xs:complexType name="soapFault">
    <xs:sequence>
      <xs:element name="code" TYPE="xs:double"/>
      <xs:element name="message" TYPE="xs:string" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
 
  <xs:complexType name="hello">
    <xs:sequence>
      <xs:element name="name" TYPE="xs:string" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
 
  <xs:complexType name="helloResponse">
    <xs:sequence>
      <xs:element name="return" TYPE="xs:string" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

Validasyon işlemi web servisin handlerı içerisinde yapılır. Handler içerisinde mesajın gelen talep mesajı olduğunun anlaşılmasından sonra messagecontexti içerisinden alınan xml verisi schema kontolünden geçirilir.

 
    PUBLIC BOOLEAN handleMessage(SOAPMessageContext messageContext) {
 
        BOOLEAN outboundProperty = (BOOLEAN) messageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
 
        SOAPMessage soapMessage = messageContext.getMessage();
 
        Result validationResult = NEW Result();       
 
 
        IF (!outboundProperty.booleanValue()) {
            try {
 
                messageContext.put("SoapRequest", toString(soapMessage));
            } catch (EXCEPTION ex) {
 
            }
                messageContext.setScope("SoapRequest", MessageContext.Scope.APPLICATION);//burdaki SET scope olmadan Params classı içerisinden çağırılamıyor !
 
                //inbound gelen talep xml li schema validasyonundan gecirilir !
                SchemaValidate VALIDATE = NEW SchemaValidate(messageContext);
 
                validationResult = VALIDATE.VALIDATE();
 
                IF (!validationResult.isResult()) {
                    throw NEW WebServiceException(validationResult.getEx());//handler içerisinde webserviceexception dönülmelidir !
                }
 
        }
 
        RETURN TRUE;
    }

Schema validasyon sonucu başarılı değil ise hata WebServiceException objesi ile fırlatılır ve hatanın dönülmesi ile client çağırısı sona erer.

Aşağıda validasyon işlemini yapan class aşağıdadır.

 
PACKAGE xx.VALIDATE;
 
import xx.fault.GenericSoapFault;
 
import JAVA.io.File;
import JAVA.io.IOException;
import JAVA.io.StringReader;
import JAVA.io.StringWriter;
import JAVA.util.Iterator;
import JAVA.util.regex.Matcher;
import JAVA.util.regex.Pattern;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import xx.fault.SoapFault;
 
/**
 *
 * @author Acer
 */
PUBLIC class SchemaValidate {
 
    PRIVATE final Result result;
    PRIVATE final SOAPMessageContext messageContext;
    PRIVATE final String schemaName = "Calc_schema1.xsd";
    static final String openingTagRegPattern = "(<)(\\w+:)(.*?>)";
    static final String tagRegPattern = "(<\\?[^<]*\\?>)?";
    static final String replaceStr = "<";
    static final String stopWord = ":";
 
 
    PUBLIC SchemaValidate(SOAPMessageContext messageContext) {
 
        this.result = NEW Result();
 
        this.messageContext = messageContext;
 
    }
 
    PUBLIC Result VALIDATE() {
 
        GenericSoapFault fault = NULL;
 
        SOAPMessage soapMessage = messageContext.getMessage();
        SOAPEnvelope soapEnv = NULL;
        SOAPBody BODY = NULL;
        String bodyString = NULL;
 
        Schema schema = NULL;
 
        try {
 
 
            soapEnv = soapMessage.getSOAPPart().getEnvelope();
            BODY = soapEnv.getBody();
 
            BODY.setPrefix("");//sonradan eklendi. NEW !
 
            bodyString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + getBodyChildAsString(BODY);
 
 
            Document document = NULL;
            document = convertStringToDom(bodyString);
            SchemaFactory factory = SchemaFactory
                    .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
            schema = factory.newSchema(NEW File(schemaName));
            javax.xml.validation.Validator validator = schema.newValidator();
 
            validator.VALIDATE(NEW DOMSource((Node) document));
 
            result.setResult(BOOLEAN.TRUE);
            result.setDescription("Validation Success");
            result.setFault(NULL);
            result.setEx(NULL);
 
        } catch (EXCEPTION ex) {
            result.setResult(BOOLEAN.FALSE);
            result.setDescription("Validation Fail");
            SoapFault faultInfo = NEW SoapFault();
            faultInfo.setCode(999);
            faultInfo.setMessage(ex.getMessage());
            fault = NEW GenericSoapFault("Soap Request Schema Validation Fail", faultInfo);
            result.setFault(fault);
            result.setEx(ex);
        } finally {
            RETURN result;
        }
    }
 
    PUBLIC static Document convertStringToDom(String xml) {//ok
        final String xmlStr = xml;
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder;
        org.w3c.dom.Document doc = NULL;
        factory.setNamespaceAware(TRUE);
        try {
            builder = factory.newDocumentBuilder();
            doc = (org.w3c.dom.Document) builder.parse(NEW InputSource(NEW StringReader(xmlStr)));
 
        } catch (EXCEPTION e) {
            e.printStackTrace();
        }
        RETURN doc;
 
    }
 
    PRIVATE String getSoapBodyAsString(SOAPBody BODY) throws TransformerConfigurationException, TransformerException {
 
        SOAPBody element = BODY;
        DOMSource source = NEW DOMSource(element);
        StringWriter stringResult = NEW StringWriter();
        TransformerFactory.newInstance().newTransformer().transform(source, NEW StreamResult(stringResult));
        String message = stringResult.toString();
 
 
        RETURN message;
 
    }
 
    PUBLIC String parseSOAPBodyToString(SOAPBody BODY) throws TransformerConfigurationException, TransformerException, SOAPException {
        String strBody = NULL;
 
        Document doc = BODY.extractContentAsDocument();
 
        Source source = NEW DOMSource(doc);
        StringWriter stringWriter = NEW StringWriter();
        StreamResult result = NEW StreamResult(stringWriter);
        TransformerFactory factory = TransformerFactory.newInstance();
        Transformer transformer = factory.newTransformer();
        transformer.transform(source, result);
        strBody = stringWriter.getBuffer().toString();
 
        RETURN strBody;
    }
 
    PRIVATE String getBodyChildAsString(SOAPBody BODY) throws TransformerException, ParserConfigurationException, SAXException, IOException {//ok!
 
 
        DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        InputSource IS = NEW InputSource();
        String docStr = getSoapBodyAsString(BODY);
        String OpeningPrefix = getOpeningTag(docStr);
 
        IS.setCharacterStream(NEW StringReader(docStr));
 
        org.w3c.dom.Document doc = db.parse(IS);
        NodeList nodes = doc.getElementsByTagName(OpeningPrefix + BODY.getFirstChild().getLocalName());
 
        TransformerFactory transFactory = TransformerFactory.newInstance();
        Transformer transformer = transFactory.newTransformer();
        StringWriter buffer = NEW StringWriter();
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
        transformer.transform(NEW DOMSource((Node) nodes.item(0)),
                NEW StreamResult(buffer));
        String str = buffer.toString();
 
        RETURN str;
    }
 
    PRIVATE static String nodeToString(Node node) {//nok!
        StringWriter sw = NEW StringWriter();
        try {
            Transformer t = TransformerFactory.newInstance().newTransformer();
            t.transform(NEW DOMSource(node), NEW StreamResult(sw));
        } catch (EXCEPTION ex) {
            _LOG.error("nodeToString Transformer Exception => ", ex);
        }
        RETURN sw.toString();
    }
 
    protected String getMethodName(MessageContext mc) {//nok!
        String operationName = NULL;
 
        try {
            SOAPMessageContext messageContext = (SOAPMessageContext) mc;
 
            // assume the operation name IS the FIRST element
            // after SOAP:BODY element
            Iterator i = messageContext.
                    getMessage().getSOAPPart().getEnvelope().getBody().getChildElements();
            WHILE (i.hasNext()) {
                Object obj = i.next();
                IF (obj instanceof SOAPElement) {
                    SOAPElement e = (SOAPElement) obj;
                    operationName = e.getElementName().getLocalName();
                    break;
                }
            }
        } catch (EXCEPTION e) {
            e.printStackTrace();
        }
        RETURN operationName;
    }
 
    PUBLIC static String removeXmlStringNamespaceAndPreamble(String xmlString) {
        RETURN xmlString.replaceAll("(<\\?[^<]*\\?>)?", "") /* remove preamble */
                .replaceAll("(<)(\\w+:)(.*?>)", "$1$3") /* remove opening tag prefix */
                .replaceAll("(</)(\\w+:)(.*?>)", "$1$3"); /* remove closing tags prefix */
 
    }
 
    PUBLIC static String getOpeningTag(String xml) {
 
        String result = "";
        Pattern pattern = NULL;
        Matcher matcher = NULL;
        String firstMatcherStr = "";
        try {
 
            pattern = Pattern.compile(openingTagRegPattern);
            matcher = pattern.matcher(xml);
 
            IF (matcher.find()) {
                firstMatcherStr = matcher.GROUP();
                pattern = Pattern.compile(tagRegPattern);
 
                String[] words = pattern.split(firstMatcherStr);
                FOR (String s : words) {
                    IF (!s.equalsIgnoreCase(stopWord)) {
                        result = result + s;
                    } ELSE {
                        result = result + stopWord;
                        break;
                    }
 
                }
                result = result.replaceAll(replaceStr, "");
 
            }
 
        } catch (EXCEPTION e) {
        } finally {
            RETURN result;
        }
 
    }
 
}

Mustafa Korkmaz

Oracle Applications Developer at Partnera
2005 yılında Dokuz Eylül Üniversitesi Endüstri Mühendisliğinden Mezun
Oldu, 2011 Yılında Ahmet Yesevi Üniversitesi Bilgisayar Mühendisliğinde
Yüksek Lisansını Tamamlandı,2012 Yılında Doğuş Üniversitesinde Bilgisayar
Mühendisliği Doktora Eğitimine Başladı.10 yılı aşkın bir zamandır Oracle
Ürünleri Uygulama Yazılım Uzmanı Olarak profesyonel kariyerine devam
etmektedir. İlgi alanları Middleware, CI/CD,
Oracle Database , PL/SQL , Java , Makine Öğrenmesi ve Veri Madenciliği alanlarındadır.
2 versiyon Oracle Database ' (10g, 11g) inde OCA(Oracle Certificate Associate) ve
PL/SQL Certificated Professional ünvanları bulunmaktadır.
Mail: mustafakorkmz@gmail.com
Mustafa Korkmaz


Yorum yapın

*