2010-07-08 6 views
5

엔드 포인트로 보내기 전에 SOAP 메시지의 내용을 수정하는 웹 서비스에 대한 인터셉터를 작성하려고합니다. 클라이언트가 일부 요소의 값이 1 인 메시지를 보낸 경우 해당 요소를 2로 변경하여 메시지가 끝점에 도착하면 클라이언트가 대신 2를 제출 한 것처럼 보입니다. 1.이 일이 나를 어렵게 만드는 어려운 일인지, 아니면 내가 필요로하는 것보다 더 힘들게 만들고있는 쉬운 일인지 확실하지 않습니다.Spring Soap 인터셉터는 어떻게 메시지 내용을 수정할 수 있습니까?

나는 스프링 인터셉터 중 일부를 밟았습니다. 유효성 검사 및 로깅 인터셉터가 모든 메시지를 변경하지는 않습니다. Wss4jSecurityInterceptor는 MessageContext에 몇 가지 속성을 추가합니다. 그러나 나는 그것이하고있는 어떤 것도 활용할 수 없었습니다. 나는 인터셉터 쉘을 가지고있다. 어떤 것도 가치있는 일은 아무것도 없습니다.

public boolean handleRequest(MessageContext messageContext, Object endpoint) 
     throws Exception { 

    SaajSoapMessage saajSoapMessage = (SaajSoapMessage) messageContext 
      .getRequest(); 
    SOAPMessage soapMessage = saajSoapMessage.getSaajMessage(); 
    SOAPBody soapBody = soapMessage.getSOAPBody(); 

    return true; 
} 

다른 사람이 이미이 특정 문제를 해결할 가능성이 있기를 바랬습니다. 모든 통찰력은 인정 될 것이다. 감사.

답변

6

페이로드 수정은 약간 까다 롭습니다. 이 작업을 수행하는 유일한 방법은 SoapBodygetPayloadSource()getPayloadResult() 메서드를 사용하는 것입니다.이 메서드는 데이터 조작을 위해 javax.xml.transform 개의 친숙한 개체를 노출합니다.

그것은 성가 시게 헤비급,하지만 당신은 이런 식으로 뭔가를 할 수 있습니다

Transformer identityTransform = TransformerFactory.newInstance().newTransformer(); 
DOMResult domResult = new DOMResult(); 
identityTransform.transform(soapBody.getPayloadSource(), domResult); 

Node bodyContent = domResult.getNode(); // modify this 

identityTransform.transform(new DOMSource(bodyContent), soapBody.getPayloadResult()); 

내가이 일을 더 나은 방법을보고 싶어요.

+0

감사합니다. 당신 말이 맞아요. 희망만큼이나 진지한 것은 아닙니다. 나는 실제로 다른 방식으로 나의 문제를 해결했다. 그것은 내 원래의 문제를 직접적으로 다루지는 않지만, 현재의 문제를 해결했습니다. – Dave

1

나중에 요청을 변경하는 것이 더 쉽다는 것을 깨달았습니다. 원래 엔드 포인트에 도달하기 전에 데이터를 수정할 수 있었던 한 원래 SOAP 메시지를 수정할 필요가 없었습니다.

모두 함께 작업하는 끝점은 AbstractDom4jPayloadEndpoint를 확장하므로 내 끝점으로 진행하기 전에 요청 요소를 수정할 수있는 프록시에서이 끝점을 래핑했습니다. 예 :

public class MyProxyEndpoint extends AbstractDom4jPayloadEndpoint 

    @Override 
    protected Element invokeInternal( 
     Element requestElement, 
     Document responseDocument) throws Exception 
    { 
     if(requestElement != null) 
     { 
      // alter request element 
     } 

     return (Element) this.invokeMethod.invoke( 
      this.target, 
      requestElement, 
      responseDocument); 
    } 
1

나는 모든 SOAP 본체 요청 내로 <authentication/> 요소를 삽입하기 위해이 답변의 코드를 수정하십시오 WebServiceMessageCallback가 문서를 변경하라고 요구하기 때문에이 솔루션은 사용

@Override 
public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException { 
    logger.trace("Enter handleMessage"); 
    try { 
     SaajSoapMessage request = (SaajSoapMessage) messageContext.getRequest(); 
     addAuthn(request); 
    } catch (Exception e) { 
     logger.error(e.getMessage(),e); 
    } 

    return true; 
} 

protected void addAuthn(SaajSoapMessage request) throws TransformerException { 
    Transformer identityTransform = TransformerFactory.newInstance().newTransformer(); 
    DOMResult domResult = new DOMResult(); 
    identityTransform.transform(request.getPayloadSource(), domResult); 

    Node bodyContent = domResult.getNode(); 
    Document doc = (Document) bodyContent; 
    doc.getFirstChild().appendChild(authNode(doc)); 

    identityTransform.transform(new DOMSource(bodyContent), request.getPayloadResult()); 
} 

protected Node authNode(Document doc) { 
    Element authentication = doc.createElementNS(ns, "authentication"); 
    Element username = doc.createElementNS(ns, "username"); 
    username.setTextContent(authn.getUsername()); 
    Element password = doc.createElementNS(ns, "password"); 
    password.setTextContent(authn.getPassword()); 
    authentication.appendChild(username); 
    authentication.appendChild(password); 
    return authentication; 
} 

하고, SaajSoapMessageFactory는 구성된 Jaxb2Marshaller에 의해 비누 바디가 삽입되기 전에 활성화됩니다.

관련 문제