title: Java - Override a WebRequest on Web Service Call
body: <p>Quick background, our company connects to an ERP system (Sage) via web services for some functions.  We have both c# (.net) and java code that performs calls to the Web Service (WS).  Recently Sage introduced <strong>Basic Authentication</strong> into their WS.</p>
  
  <p>Please note:  This is a <strong>JAVA</strong> question, but I'll show an example in C# first to explain.</p>
  
  <p>In the c# program, I first would create an object that is for accessing the WS:</p>
  
  <pre><code>                var sageService = new CAdxWebServiceXmlCCServiceBasicAuth();
  </code></pre>
  
  <p>I then set up credential information:</p>
  
  <pre><code>                var sageServiceCallContext = SageFactory.Instance.GetCallContext();
  
              sageService.Credentials = new NetworkCredential(SageUser, SagePwd);      
              sageService.PreAuthenticate = true;
  </code></pre>
  
  <p>then finally the call to the specific web service method:</p>
  
  <pre><code>                    sageCustomerSvcResponse = sageService.run(sageServiceCallContext, "YTDPROF", sageCustomerRequestInXml);
  </code></pre>
  
  <p>When I set up the service object I use a custom class that looks like this:</p>
  
  <pre><code>    public class CAdxWebServiceXmlCCServiceBasicAuth : CAdxWebServiceXmlCCService
  {
      protected override WebRequest GetWebRequest(Uri uri)
      {
          HttpWebRequest webRequest = (HttpWebRequest)base.GetWebRequest(uri);
  
          NetworkCredential credentials = Credentials as NetworkCredential;
          if (credentials != null)
          {
              string authInfo = "";
              if (credentials.Domain != null &amp;&amp; credentials.Domain.Length &gt; 0)
              {
                  authInfo = string.Format(@"{0}\{1}:{2}", credentials.Domain, credentials.UserName, credentials.Password);
              }
              else
              {
                  authInfo = string.Format(@"{0}:{1}", credentials.UserName, credentials.Password);
              };
              authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
              webRequest.Headers["Authorization"] = "Basic " + authInfo;
          }
          return webRequest;
      }
  
  }
  </code></pre>
  
  <p>What happens is that now, when I perform any call to the web service methods, the GetWebRequest from the class is invoked every time.  This is how we implemented basis authentication in c#.</p>
  
  <p>How do I do this in Java?</p>
  
  <p>In the java code currently, I create the service object (that which accesses the web services) this way:</p>
  
  <pre><code>WebServiceInvoker service = new WebServiceInvoker(SageWSURL,""); 
  </code></pre>
  
  <p>and the WebServiceInvoker looks like this (truncated for brevity):</p>
  
  <pre><code>    public WebServiceInvoker(String url, String dummy) throws ServiceException, IOException {
      serviceLocator = new CAdxWebServiceXmlCCServiceLocator();
      service = serviceLocator.getCAdxWebServiceXmlCC(url);  
      cc = new CAdxCallContext();
      cc.setCodeLang("ENG");
      cc.setCodeUser("USER");
      cc.setPassword("PAWWORD"); 
      cc.setPoolAlias("POOL"); 
      cc.setRequestConfig("adxwss.trace.on=on&amp;adxwss.trace.size=16384&amp;adonix.trace.on=on&amp;adonix.trace.level=3&amp;adonix.trace.size=8");
      log = new PrintWriter(new BufferedWriter(new FileWriter("C:/Kalio/service/orders/log.txt")));
  }
  </code></pre>
  
  <p>the webservice locator looks like this:</p>
  
  <pre><code>public class CAdxWebServiceXmlCCServiceLocator extends org.apache.axis.client.Service implements com.adonix.www.WSS.CAdxWebServiceXmlCCService {
  
  public CAdxWebServiceXmlCCServiceLocator() {
  }
  
      public com.adonix.www.WSS.CAdxWebServiceXmlCC getCAdxWebServiceXmlCC() throws javax.xml.rpc.ServiceException {
     java.net.URL endpoint;
     System.out.println("using local Sage Web Servivce URL:" + CAdxWebServiceXmlCC_address);
  
      try {
          endpoint = new java.net.URL(CAdxWebServiceXmlCC_address);
      }
      catch (java.net.MalformedURLException e) {
          throw new javax.xml.rpc.ServiceException(e);
      }
      return getCAdxWebServiceXmlCC(endpoint);
  }
  
  public com.adonix.www.WSS.CAdxWebServiceXmlCC getCAdxWebServiceXmlCC(java.net.URL portAddress) throws javax.xml.rpc.ServiceException {
      try {
          com.adonix.www.WSS.CAdxWebServiceXmlCCSoapBindingStub _stub = new com.adonix.www.WSS.CAdxWebServiceXmlCCSoapBindingStub(portAddress, this);
          _stub.setPortName(getCAdxWebServiceXmlCCWSDDServiceName());
          return _stub;
      }
      catch (org.apache.axis.AxisFault e) {
          return null;
      }
  }
  </code></pre>
  
  <p>and the specific method within that class is this:</p>
  
  <pre><code>    public String getCustomer(String constructedXML) throws RemoteException {
      **CAdxResultXml result = service.run(cc, "XTDPROF", constructedXML);**
      CAdxMessage[] messages = result.getMessages();
      for (int i = 0; i&lt;messages.length; i++) {
          CAdxMessage message = messages[i];
          log.println("X3 get customer message: " + message.getMessage());
          log.println("X3 get customer message type: " + message.getType());
      }
      return result.getResultXml();
  }
  </code></pre>
  
  <p>So my questions is, how to I emulate that <strong>override</strong> that I see in the .net program in Java?  It seems like it would be somewhere in either the service locator or invoker, but the program does not use standard http classes, but this adxwss stuff.  I tried a straight c# to java conversion and that way didn't help.  I have seen examples where basicAuth is implemented, but not against web service calls.  </p>
  
  <p>The c# is pretty clear cut, because once I create the service object using the basicAuth override, every web service calls goes through the orderride.  How does that happen in Java?</p>
  
  <p>I'll be happy to provide more info if needed and I'll continue to look/experiment, but at the moment I'm treading water.</p>
  
  <p>Adding:</p>
  
  <p>In tracing through the java code I found the specific web service call (run) where an apache "call" object is created.  Is this where basicauth can be added?</p>
  
  <pre><code>    public com.adonix.www.WSS.CAdxResultXml run(com.adonix.www.WSS.CAdxCallContext callContext, java.lang.String publicName, java.lang.String inputXml) throws java.rmi.RemoteException {
      if (super.cachedEndpoint == null) {
          throw new org.apache.axis.NoEndPointException();
      }
      org.apache.axis.client.Call _call = createCall();
      _call.setOperation(_operations[0]);
      _call.setUseSOAPAction(true);
      _call.setSOAPActionURI("");
      _call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);
      _call.setOperationName(new javax.xml.namespace.QName("http://www.adonix.com/WSS", "run"));
  
      setRequestHeaders(_call);
      setAttachments(_call);
   try {        java.lang.Object _resp = _call.invoke(new java.lang.Object[] {callContext, publicName, inputXml});
  
      if (_resp instanceof java.rmi.RemoteException) {
          throw (java.rmi.RemoteException)_resp;
      }
      else {
          extractAttachments(_call);
          try {
              return (com.adonix.www.WSS.CAdxResultXml) _resp;
          } catch (java.lang.Exception _exception) {
              return (com.adonix.www.WSS.CAdxResultXml) org.apache.axis.utils.JavaUtils.convert(_resp, com.adonix.www.WSS.CAdxResultXml.class);
          }
      }
    } catch (org.apache.axis.AxisFault axisFaultException) {
    throw axisFaultException;
  }
  }
  </code></pre>