2012-11-08 6 views
6

Ich muss die vollständige HTTP-Anfrage und Antwort in einem JAX-WS WebService-Aufruf protokollieren. Für die Anfrage benötige ich die Anforderungsheader und den Hauptteil und für die Antwort, die Antwortheader und den Hauptteil.Log jax-ws http Anfrage und Antwort

Nach einiger Forschung, habe ich festgestellt, dass ich diese Informationen mit der Eigenschaft erhalten kann:

-Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true 

und die Informationen an, die ich brauche, aber es gibt sie an die Konsole und ich brauche es zu speichern in die Datenbank mit einer internen Anforderungs-ID.

Ich habe versucht, einen Handler zu implementieren:

public class LoggingHandler implements SOAPHandler<SOAPMessageContext> { 

    @Override 
    public boolean handleMessage(SOAPMessageContext context) { 
     Boolean outbound = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); 
     if (outbound) { 
      System.out.println("SOAP outbound!!!!!"); 
      Map<String, List<String>> responseHeaders = (Map<String, List<String>>) context 
        .get(SOAPMessageContext.HTTP_RESPONSE_HEADERS); 
      try { 
       String headers = getHeaders(responseHeaders); 
       System.out.println(headers); 
       String body = getBody(context.getMessage()); 
       System.out.println(body); 
      } catch (Exception ex) { 
       // TODO: What do I have to do in this case? 
      } 
     } else { 
      System.out.println("SOAP inbound!!!!!"); 
      Map<String, List<String>> requestHeaders = (Map<String, List<String>>) context 
        .get(SOAPMessageContext.HTTP_REQUEST_HEADERS); 
      try { 
       String headers = getHeaders(requestHeaders); 
       System.out.println(headers); 
       String body = getBody(context.getMessage()); 
       System.out.println(body); 
      } catch (Exception ex) { 
       // TODO: What do I have to do in this case? 
      } 
     } 
     return true; 
    } 

    private String getBody(SOAPMessage message) throws SOAPException, IOException { 
     OutputStream stream = new ByteArrayOutputStream(); 
     message.writeTo(stream); 
     return stream.toString(); 
    } 

    public String getFullHttpRequest(HttpServletRequest request) throws IOException { 
     InputStream in = request.getInputStream(); 
     String encoding = request.getCharacterEncoding(); 
     encoding = encoding == null ? "UTF-8" : encoding; 
     String body = IOUtils.toString(in, encoding); 
     return body; 
    } 

    private String getHeaders(Map<String, List<String>> headers) throws IOException { 
     StringBuffer result = new StringBuffer(); 
     if (headers != null) { 
      for (Entry<String, List<String>> header : headers.entrySet()) { 
       if (header.getValue().isEmpty()) { 
        // I don't think this is legal, but let's just dump it, 
        // as the point of the dump is to uncover problems. 
        result.append(header.getValue()); 
       } else { 
        for (String value : header.getValue()) { 
         result.append(header.getKey() + ": " + value); 
        } 
       } 
       result.append("\n"); 
      } 
     } 
     return result.toString(); 
    } 

} 

aber in diesem Fall kann ich die http-Request-Header und Körper, sondern in der Antwort zu bekommen, erhalte ich nur den Körper, sind http-Response-Header immer leer.

Irgendeine Idee, wie man das schafft? Ziel ist es, die vollständige HTTP-Anfrage und Antwort in einer Datenbank speichern zu können.

Danke !!

Antwort

2

Sie könnten auch versuchen,

-Dcom.sun.xml.ws.transport.http.HttpAdapter.dump=true 

Ich nehme an, Sie in einem Java-EE-Anwendungsserver von einer Art Ihres Web-Service sind die Bereitstellung (und nicht von einem Standalone-Client). Sie können keinen Zugriff auf die Java EE-Infrastruktur wie HttpServletRequest und HttpServletResponse außerhalb des Kontexts eines Web-/Java EE-Containers haben.

Sie könnten versuchen, die Hände auf dem tatsächlichen Servlet Response-Objekt zu erhalten (in einem Web-Kontext) mit

HttpServletResponse response = (HttpServletResponse) messageContext.get(SOAPMessageContext.SERVLET_RESPONSE); //messageContext is the SOAPMessageContext 
    List<String> responseHeaderNames = (List<String>)response.getHeaderNames(); 
     for(String headerName : responseHeaderNames){ 
      //Do whatever you want with it. 
       } 

ich, dass Sie ernsthaft zweifeln, werden in der Lage, Ihre Hände auf den vollen Response-Header zu erhalten innerhalb ein Handler obwohl. Deine Frage hat mich wirklich fasziniert und ich habe viel Zeit damit verbracht, diesen Teil zu erforschen. In allen Codebeispielen, die ich gesehen habe, nicht einmal das Beispiel auf dem metro site Versuch, diese Funktionalität zu implementieren, und ich denke, der Grund ist einfach. An dem Punkt, an dem ein Handler aufgerufen wird, verfügt der Container möglicherweise nicht über ausreichende definitive Informationen zum Stempeln eines http-Headers für die ausgehende Nachricht. Sie können vielleicht etwas hinzufügen, aber das ist auch zweifelhaft.

+0

Vielen Dank für Ihre Antwort. Ich stelle den Webservice mit Spring 3 auf einem Tomcat-Anwendungsserver bereit. Dein erster Vorschlag wird nur auf die Konsole übertragen, oder? Ich muss es in einer Datenbank speichern können und bezüglich der zweiten Option werde ich es versuchen. Vielen Dank! – drublik

+0

@druk sicher, lassen Sie uns wissen, wie es funktioniert. Ich bin neugierig auf eine – kolossus

+0

Danke für Ihre Antwort, aber HttpServletResponse hat keine "getHeaderNames()" -Methode. In der Tat scheint es, dass es keine Methode hat, Header zu erhalten, nur um zu setzen. Diese Funktion befindet sich nur in HttpServletRequest. – drublik

Verwandte Themen