如何将传入的 cookie 获取到 Mule HTTP 端点

How to get the incoming cookies to a Mule HTTP end point

我正在使用 Mule EE 3.5.2。 我正在将带有 cookie header 的 HTTP 请求 (PostMan) 发布到 Mule 中的传入 HTTP 端点。我如何读取这个 Cookie? 实际上,这个 cookie 将通过 NGinX 代理;我需要它传递给另一个应用程序。

首先确保您的连接器具有 enableCookies="true".

然后您会找到一个类型为 Lorg.apache.commons.httpclient.Cookie 的名为 cookies 的 inboundProperty。

只需#[message.inboundProperties['cookies']即可访问它们。

新的 http:listener 组件不再适用。 设置 属性 将给出:

    org.xml.sax.SAXParseException: cvc-complex-type.3.2.2: Attribute 'enableCookies' is not allowed to appear in element 'http:listener'.

那么如何使用新的 http:listener 组件做到这一点... 我遇到的一个问题是我需要访问传入的 cookie,而 Mule 只提供未格式化字符串中的 cookie。

这是我的一个朋友开发的一个选项,我对其进行了一些增强,以便轻松访问流中的 cookie:

package transformers;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.mule.api.MuleMessage;
import org.mule.api.transformer.TransformerException;
import org.mule.api.transport.PropertyScope;
import org.mule.transformer.AbstractMessageTransformer;
import org.mule.transport.http.CookieHelper;
import org.apache.commons.httpclient.Cookie;

public class CookieGrabber extends AbstractMessageTransformer {

    public Object transformMessage(MuleMessage message, String outputEncoding) throws TransformerException {
        Object              _CookieHeader   = message.getInboundProperty("Cookie");
        List<Cookie>        _CookieList     = null;
        Map<String,String>  _CookieMap      = new HashMap<String,String>();

        try {
            //Grab the cookies from the header and put them into a List
            _CookieList = (List<Cookie>) Arrays.asList(CookieHelper.parseCookiesAsAServer(_CookieHeader.toString(), 
                                                                                           new URI("" + message.getInboundProperty("host"))));
            //And put them in a convenient List which can be accessed from the flow
            message.setProperty("incomingCookieList", _CookieList, PropertyScope.SESSION);

            //Let's also put them in a nice Map, since incoming cookies will 
            //usually only contain a name and a value, so let's get easy access to them by their name.
            for (Cookie _Cookie : _CookieList){
                _CookieMap.put(_Cookie.getName(), _Cookie.getValue());
            }
            message.setProperty("incomingCookieMap", _CookieMap, PropertyScope.SESSION);

        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        return message;
    }
}

然后是这个流程示例,展示了如何使用这个代码片段。 它包含一个设置一些 cookie 的侦听器,将其转发给 "proxy",后者将读取 cookie,但也会将请求转发到另一个端点,使其成为透明代理,但它会在进程中读取 cookie。

<?xml version="1.0" encoding="UTF-8"?>
<mule   xmlns:json="http://www.mulesoft.org/schema/mule/json" 
        xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" 
        xmlns:http="http://www.mulesoft.org/schema/mule/http" 
        xmlns="http://www.mulesoft.org/schema/mule/core" 
        xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
        xmlns:spring="http://www.springframework.org/schema/beans" 
        version="EE-3.6.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd">
    <custom-transformer     class="transformers.CookieGrabber" 
                            name="MyCookieTranformer" 
                            doc:name="Java"/>
    <http:listener-config   name="HTTP_Configuration_CookieHandlerExample" 
                            host="0.0.0.0" 
                            port="8080" 
                            doc:name="HTTP Listener Configuration"/>
    <http:request-config    name="HTTP_Request_Configuration" 
                            host="localhost" 
                            port="8080" 
                            doc:name="HTTP Request Configuration"/>
    <flow name="CookieSetterFlow">
        <http:listener      config-ref="HTTP_Configuration_CookieHandlerExample" 
                            path="/setCookies/*" 
                            doc:name="setCookies" 
                            doc:description="Call this module by entering http://localhost:8080/setCookie"/>
        <message-properties-transformer doc:name="Set the cookies" 
                                        doc:description="Set some random cookies in the header">
            <add-message-property       key="Cookie" 
                                        value="token=abcde; name=dennis"/>
        </message-properties-transformer>
        <http:request       config-ref="HTTP_Request_Configuration" 
                            path="/proxyCookie" 
                            method="GET" 
                            doc:name="call proxyCookies" 
                            doc:description="Invoke the cookieReceiver with the cookies we've just set. Note the failure status code validator with a non-existing http code. It's a nasty bug, but it works like this...">
            <http:failure-status-code-validator values="00000"/>
        </http:request>
    </flow>
    <flow name="CookieProxyFlow">
        <http:listener      config-ref="HTTP_Configuration_CookieHandlerExample" 
                            path="/proxyCookie" 
                            doc:name="proxyCookies" 
                            doc:description="This connector will proxy the cookieReceiver"/>
        <transformer        ref="MyCookieTranformer" 
                            doc:name="GrabCookies" 
                            doc:description="Use our custom transformers.CookieGrabber class to put the cookies in a nice java.util.List in a session variable."/>
        <logger             message="CookieProxy: Value of cookie &quot;token&quot;: &quot;#[sessionVars.incomingCookieMap.get('token')]&quot;." 
                            level="INFO" 
                            doc:name="Have a cookie!" 
                            doc:description="Let get a cookie value, simply by referring the name of it as the key from our map"/>
        <flow-ref           name="copy-and-clean-headers" 
                            doc:name="copy-and-clean-headers" 
                            doc:description="Cope the headers and clean the Mule stuff from the headers to forward it clean to the receiver."/>
        <set-property       propertyName="host" 
                            value="localhost" 
                            doc:name="Set Host" 
                            doc:description="Now not really necessary, but you'll probably want to set the hostname to the actual service endpoint."/>
        <http:request       config-ref="HTTP_Request_Configuration" 
                            path="/receiveCookie" 
                            method="GET" 
                            doc:name="forward to receiveCookies" 
                            doc:description="Invoke the cookieReceiver.">
            <http:failure-status-code-validator values="00000"/>
        </http:request>
        <flow-ref           name="copy-and-clean-headers" 
                            doc:name="copy-and-clean-headers" 
                            doc:description="Again copy the headers and clean the Mule http stuff."/>
    </flow>
    <sub-flow name="copy-and-clean-headers" >
        <copy-properties    propertyName="*" 
                            doc:name="Copy All HTTP Headers"/>
        <remove-property    propertyName="Content-Length" 
                            doc:name="Remove Content Length"/>
        <remove-property    propertyName="MULE_*" 
                            doc:name="Remove MULE Properties"/>
        <remove-property    propertyName="X_MULE*" 
                            doc:name="Remove X_MULE Properties"/>
        <remove-property    propertyName="http.*" 
                            doc:name="Remove http Properties"/>
    </sub-flow>
    <flow name="CookieReceiverFlow">
        <http:listener      config-ref="HTTP_Configuration_CookieHandlerExample" 
                            path="/receiveCookie" 
                            doc:name="receiveCookies" 
                            doc:description="This connector receives the cookies we've just set"/>
        <transformer        ref="MyCookieTranformer" 
                            doc:name="GrabCookies" 
                            doc:description="Use our custom transformers.CookieGrabber class to put the cookies in a nice java.util.List in a session variable."/>
        <logger             message="CookieReceiver: Value of cookie &quot;token&quot;: &quot;#[sessionVars.incomingCookieMap.get('token')]&quot;. Yep, still there :)" 
                            level="INFO" 
                            doc:name="Have a cookie!" 
                            doc:description="Let get a cookie value, simply by referring the name of it as the key from our map"/>
        <set-payload        value="#[sessionVars.incomingCookieList.toArray(String)]" 
                            doc:name="Put CookieList to payload" 
                            doc:description="Put the session vairable List that contains the cookies in the payload"/>
        <json:object-to-json-transformer    returnClass="java.lang.String" 
                                            doc:name="Object to JSON" 
                                            doc:description="Convert our payload to a JSON object"/>
    </flow>
</mule>

您可以通过 运行 测试它并打开此页面:http://localhost:8080/setCookies

希望这对您有所帮助。

下面是如何在没有自定义 java class.

的会话变量中保存来自剩余响应的 cookie
<set-session-variable variableName="incomingCookies" value="#[org.mule.transport.http.CookieHelper.parseCookiesAsAClient(message.inboundProperties['set-cookie'],null)]" doc:name="Set incomingCookies as Session Variable"/>
<set-variable variableName="cookie-name" value="#[org.mule.transport.http.CookieHelper.getCookieValueFromCookies(incomingCookieMap,'cookie-name')]" doc:name=“Set cookie-name as Flow Variable”/>

您可以使用类似的方法从 CookieHelper class.

中使用 parseCookiesAsAServer 方法从休息请求中提取 cookie

有关 CookieHelper class 的更多信息在此处 https://www.mulesoft.org/docs/site/3.8.0/apidocs/org/mule/transport/http/CookieHelper.html

您可以通过以下方式获取 cookie:

#[headers:INBOUND:cookie] or #[message.inboundProperties['cookie']]