Home » Java » SOAPHandler weird behavior

SOAPHandler weird behavior

Posted by: admin August 16, 2018 Leave a comment

Questions:

I have the following SOAPHandler

package fi.***.ws;

import java.io.StringWriter;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Set;

import javax.ejb.EJB;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

import ***

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class MyLoggingHandler implements SOAPHandler<SOAPMessageContext> {

    @EJB private AsetusDAO asetusDAO;
    @EJB private SanomalokiDAO sanomalokiDAO;

    public void tallennaLokirivi(Suunta suunta, String palvelu, String sanoma) {
        Sanomaloki loki = new Sanomaloki();
        loki.setSuunta(new BigDecimal(suunta.getValue()));
        loki.setPalvelu(palvelu);
        loki.setSanoma(sanoma);
        sanomalokiDAO.tallennaLokirivi(loki);
    }

    public String getPalvelu(SOAPMessageContext ctx) {
        SOAPEnvelope msg;
        SOAPBody body;
        String operationName;
        try {
            msg = ctx.getMessage().getSOAPPart().getEnvelope();
            body = msg.getBody();
            operationName = body.getChildNodes().item(1).getLocalName();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }

        return operationName;
    }

    public String getSanomaXML(SOAPMessageContext ctx) {
        SOAPMessage message;
        String sanomaXML;

        final StringWriter sw = new StringWriter();

        try {
            message = ctx.getMessage();
            TransformerFactory.newInstance().newTransformer().transform(
                new DOMSource(message.getSOAPPart()),
                new StreamResult(sw));
            sanomaXML = sw.toString();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }

        return sanomaXML;
    }

    public boolean isSanomalokiPaalla() {
        Asetus lokitus = asetusDAO.haeAsetus(AsetusDAO.Avain.A1_SANOMALOKI_PAALLA);
        return DatabaseConstants.A1_SANOMALOKI_PAALLA_1_VALUE.equals(lokitus.getArvo());
    }

    @Override
    public boolean handleMessage(SOAPMessageContext context) {

        if (!isSanomalokiPaalla())
            return true;

        String palvelu = getPalvelu(context);
        String sanoma = getSanomaXML(context);

        boolean isRequest = !((Boolean) context.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY)).booleanValue();

        if (isRequest) {
            // request
            System.out.println("--- Logging handler message request ---");
            tallennaLokirivi(Suunta.SISAAN, palvelu, sanoma);

        } else {
            // response
            System.out.println("--- Logging handler message response ---");
            tallennaLokirivi(Suunta.ULOS, palvelu, sanoma);
        }
        return true; // return false;
    }

    @Override
    public boolean handleFault(SOAPMessageContext context) {

        if (!isSanomalokiPaalla())
            return true;

        System.out.println("--- Logging handler message fault ---");

        String palvelu = getPalvelu(context);
        String sanoma = getSanomaXML(context);

        tallennaLokirivi(Suunta.ULOS, palvelu, sanoma);

        return true; // return false;
    }

    @Override
    public void close(MessageContext context) {
        System.out.println("--- close ---");
    }

    @Override
    public Set<QName> getHeaders() {
        System.out.println("--- getHeaders---");
        return Collections.emptySet();
    }

}

Invoking the web service returns a following fault

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
   <S:Body>
      <ns0:Fault xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.w3.org/2003/05/soap-envelope">
         <faultcode>ns0:Server</faultcode>
         <faultstring>Exception Description: The object [?], of class [class java.lang.String], from mapping [org.eclipse.persistence.oxm.mappings.XMLDirectMapping[x-->x/text()]] with descriptor [XMLDescriptor(fi.***.PisteTyyppi --> [])], could not be converted to [class java.lang.Integer].
Internal Exception: java.lang.NumberFormatException: For input string: "?"</faultstring>
      </ns0:Fault>
   </S:Body>
</S:Envelope>

It is the getPalvelu and getSanomaXML methods which causes this fault. However, for some reason the exception is not caught by the catch clause. handleMessage method actually finishes without handleFault method getting called. Also, if I remove those methods from the handler, web service implementation binds parameters kindly and doesn’t throw any fault.

Obviously the Java SOAP API internally catches the exception and sets the fault. Why I get this fault at the handler, and is there any way to catch the exception?

Answers: