2013-08-01 74 views
2

我需要創建一個具有特定名稱的Cookie,以便在我的Web服務調用中發送到具有基於它的路由邏輯的另一個網絡。在SOAP消息處理程序內的HTTP標頭中設置自定義Cookie

當我嘗試設置爲HTTP標頭在我的SOAP處理器使用

headers.put("Cookie", Collections.singletonList(cookiename + "='" + cookieValue + "'")); 

它的工作原理是第一次。

對此的迴應帶有一個JSESSIONID的Set-Cookie

我的後續請求認爲JSESSIONID及其在cookie中的價值,並忽略設置我的自定義cookie。

有沒有辦法確保我的cookie在所有請求中默認設置?

+0

也許你的cookie被存儲在數據庫中的web服務的終端和服務器只給你一個會話ID的服務。順便說一下,你是否嘗試過一個自定義HTTP頭,比如「X-MyCustomHeader:my value」,而不是Cookie頭? –

回答

2

最近我們還需要使用SOAP服務來支持JSESSIONID,這就是我們在閱讀StackOverflow並引用IBM站點上的SSO客戶端示例後想出的。

我們擴展了SOAPHandler

import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.Map; 
import java.util.Set; 
import java.util.List; 

import javax.xml.ws.handler.MessageContext; 
import javax.xml.ws.handler.soap.SOAPHandler; 
import javax.xml.ws.handler.soap.SOAPMessageContext; 

import com.sun.istack.internal.Nullable; 

public class SoapMessageHandler implements SOAPHandler<SOAPMessageContext> { 

    private String sessionCookie = ""; 

    @Override 
    public void close(MessageContext arg0) { } 

    @SuppressWarnings({ "rawtypes", "unchecked" }) 
    @Override 
    public Set getHeaders() { 
     return null; 
    } 

    @Override 
    public boolean handleFault(SOAPMessageContext context) { 
     return false; 
    } 

    @Override 
    public boolean handleMessage(SOAPMessageContext soapMessageContext) { 
     if ((Boolean) soapMessageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY)) { 
      // Add header to outbound request (set cookie in HTTP client header) 
      // Set the Cookie 
      Map<String, List<String>> headers = (Map<String, List<String>>)soapMessageContext.get(MessageContext.HTTP_REQUEST_HEADERS); 
      if (headers == null) { 
       headers = new HashMap<String, List<String>>(); 
       soapMessageContext.put(MessageContext.HTTP_REQUEST_HEADERS, headers); 
      } 
      List<String> cookie = headers.get("Cookie"); 
      if (cookie == null) { 
       cookie = new ArrayList<String>(); 
       headers.put("Cookie", cookie); 
      } 
      cookie.add(sessionCookie); 
     } else { 
      // Read header from request (read cookie from server's HTTP headers) 
      Map<String, List<String>> map = (Map<String, List<String>>) soapMessageContext.get(MessageContext.HTTP_RESPONSE_HEADERS); 
      List<String> contentType = getHTTPHeader(map, "Set-Cookie"); 
      // Note, only grabs last cookie value! 
      // If you need to present more than one cookie you could make 
      // sessionCookie a List<String> and modify this class accordingly. 
      if (contentType != null) { 
       StringBuffer strBuf = new StringBuffer(); 
       for (String type : contentType) { 
        strBuf.append(type); 
       } 
       sessionCookie = strBuf.toString(); 
      } 
     } 
     return true; 
    } 

    private @Nullable List<String> getHTTPHeader(Map<String, List<String>> headers, String header) { 
     for (Map.Entry<String, List<String>> entry : headers.entrySet()) { 
      String name = entry.getKey(); 
      if (header != null && name !=null) { 
       if (name.equalsIgnoreCase(header)) 
        return entry.getValue(); 
      } 
     } 
     return null; 
    } 

} 

這也需要HandlerResolver

import java.util.ArrayList; 
import java.util.List; 
import javax.xml.ws.handler.Handler; 
import javax.xml.ws.handler.HandlerResolver; 
import javax.xml.ws.handler.PortInfo; 

public class SoapHandlerResolver implements HandlerResolver { 

@SuppressWarnings("unchecked") 
public List<Handler> getHandlerChain(PortInfo portInfo) { 
     List<Handler> handlerChain = new ArrayList<Handler>(); 
     handlerChain.add(new SoapMessageHandler()); 
     return handlerChain; 
    } 
} 

擴展HandlerResolver調用,像這樣的SOAP服務時,則調用:

ExampleService exampleService = new ExampleService(); 
exampleService.setHandlerResolver(new SoapHandlerResolver()); 
Example example = exampleService.getExampleServicePort(); 
example.myMethod(); 

對於我們來說,這對於Java 6來說是有效的,但僅限於支持一個Cookie標頭(儘管可以進行簡單修改以支持多個Cookie標頭)。

注意:如果像我們一樣,你必須通過多個服務之間的相同的會話cookie(好象在SOAP服務餅乾還不夠糟糕)而不是此:

private String sessionCookie = ""; 

你可以只做到這一點:

static private String sessionCookie = ""; 

這是超級哈克,並可能會或可能不是你根據服務(和你的代碼)是如何工作的,以及如何可以會話,你可以對遠程服務的工作,所以我建議比在生產中使用靜態更復雜的東西。

0

確切的說:

SOAPHandler類中,我們需要通過會話ID爲JSESSIONID="actual ID"。以下是完整的代碼。

import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
import java.util.Set; 

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.JAXBException; 
import javax.xml.namespace.QName; 
import javax.xml.soap.Name; 
import javax.xml.soap.SOAPElement; 
import javax.xml.soap.SOAPException; 
import javax.xml.soap.SOAPFactory; 
import javax.xml.soap.SOAPHeader; 
import javax.xml.soap.SOAPHeaderElement; 
import javax.xml.soap.SOAPMessage; 
import javax.xml.ws.LogicalMessage; 
import javax.xml.ws.ProtocolException; 
import javax.xml.ws.handler.LogicalMessageContext; 
import javax.xml.ws.handler.MessageContext; 
import javax.xml.ws.handler.soap.SOAPMessageContext; 

public class SOAPHandler implements 
javax.xml.ws.handler.soap.SOAPHandler<SOAPMessageContext> { 

public Set<QName> getHeaders() { 
return null; 
} 

public void close(MessageContext mc) { 
} 

public boolean handleFault(SOAPMessageContext mc) { 
return true; 
} 

public boolean handleMessage(SOAPMessageContext mc) { 
    System.out.println("Setting this before call"); 
if (Boolean.TRUE.equals(mc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY))) { 
    HandlerUtils.printMessageContext("Client SOAPHandler", mc); 
    SOAPMessage sm = mc.getMessage(); 


    // Add header to outbound request (set cookie in HTTP client header) 
    // Set the Cookie 
    Map<String, List<String>> headers = (Map<String, List<String>>)mc.get(MessageContext.HTTP_REQUEST_HEADERS); 
    if (headers == null) { 
     headers = new HashMap<String, List<String>>(); 
     mc.put(MessageContext.HTTP_REQUEST_HEADERS, headers); 
    } 
    List<String> cookie = headers.get("Cookie"); 
    if (cookie == null) { 
     cookie = new ArrayList<String>(); 
     headers.put("Cookie", cookie); 
    } 
    cookie.add("JSESSIONID=DBE5B99503B8F4B7EF76F4959D223B3B"); 
} 

return true; 
} 
} 

再進行試驗,

public class ServiceTest { 
    public static void main(String[] args) throws SFWebServiceFaultException { 

    //Create object for service class, to get the port and call service method. 
    PersonServiceImplService service = new PersonServiceImplService(); 
    PersonService port = service.getPersonServiceImplPort(); 
    SOAPHandler handler = new SOAPHandler(); 

    //Add the Handler to List 
    List<Handler> handlerChain = new ArrayList<Handler>(); 
    handlerChain.add(handler); 

    //Bind the handler to service 
    ((BindingProvider) port).getBinding().setHandlerChain(handlerChain);  

    //Call the service method 
    System.out.println(port.greetPerson("Ganesh")); 
    } 
} 
+0

引用網址/好資源:https://web-gmazza.rhcloud.com/blog/entry/jaxws-handler-tutorial – Ethiraj

相關問題