2013-08-01 71 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

相关问题