首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在SOAP消息处理程序中的HTTP标头中设置自定义cookie

在SOAP消息处理程序中的HTTP标头中设置自定义cookie
EN

Stack Overflow用户
提问于 2013-08-01 23:16:13
回答 2查看 8.1K关注 0票数 3

我需要创建一个具有特定名称的Cookie,它将在我的web服务调用中发送到另一个具有基于它的路由逻辑的网络。

当我尝试将SOAP处理程序中的HTTP头设置为

代码语言:javascript
运行
复制
headers.put("Cookie", Collections.singletonList(cookiename + "='" + cookieValue + "'")); 

它第一次起作用了。

对此的响应提供了一个用于JSESSIONID的Set-Cookie。

随后的请求保存了JSESSIONID及其在cookie中的值,并忽略了设置自定义cookie。

是否有办法确保在所有请求中默认设置我的cookie?

EN

回答 2

Stack Overflow用户

发布于 2014-07-07 15:49:05

我们最近还需要使用SOAP服务支持JSESSIONID,这就是我们在阅读StackOverflow并引用IBM站点上的SSO客户端示例后得出的结果。

我们扩展了SOAPHandler

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
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;
   }
}

然后,在调用SOAP服务时调用扩展的HandlerResolver,如下所示:

代码语言:javascript
运行
复制
ExampleService exampleService = new ExampleService();
exampleService.setHandlerResolver( new SoapHandlerResolver() );
Example example = exampleService.getExampleServicePort();
example.myMethod();

对于Java 6来说,这是可行的,它的限制是只支持一个Cookie头(尽管可以对其进行轻微的修改以支持多个Cookie头)。

注意:如果像我们一样,您必须在多个服务之间传递相同的会话cookie (就好像SOAP服务上的cookie还不够坏一样),而不是这样:

代码语言:javascript
运行
复制
private String sessionCookie = "";

你可以这么做:

代码语言:javascript
运行
复制
static private String sessionCookie = "";

这是超级讨厌的,并且可能对您起作用,也可能不起作用,这取决于服务(和您的代码)是如何工作的,以及您如何在远程服务上使用会话,因此,我建议您在生产中使用静态更复杂的东西。

票数 5
EN

Stack Overflow用户

发布于 2017-07-19 10:24:07

准确地说:

SOAPHandler类中,我们需要将会话id作为JSESSIONID="actual ID"传递。下面是完整的代码。

代码语言:javascript
运行
复制
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;
}
}

然后测试服务

代码语言:javascript
运行
复制
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"));
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18006210

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档