簡體   English   中英

在WebLogic上設置默認的CookieManager無效

[英]Setting a default CookieManager on WebLogic has no effect

我正在使用Spring的WebServiceGatewaySupport連接到供應商的SOAP Web服務。 該服務的要求之一是客戶端必須維護服務器發送的會話cookie。

我能夠確定WebServiceGatewaySupport在內部使用HttpURLConnection類進行請求。 只需致電

CookieHandler.setDefault(new CookieManager());

在聚會開始之前,添加了一個默認的cookie管理器,並且一切正常,我本地的Tomcat實例上都表現出了桃紅色的感覺(我什至注意到機器旁出現了一條小彩虹)。

但是,當我部署到WebLogic 10.3.6.0時,一切都會全部完成。 它不像以前那樣笨拙,並且我的Cookie被扔了。

通過重寫CookieManager的get和put方法,我能夠證明WebLogic是元凶。 在Tomcat中對此采取了大量措施。 WebLogic對此不以為然。

    CookieHandler.setDefault(new CookieManager() {
        @Override
        public Map<String, List<String>> get(URI uri, Map<String, List<String>> stringListMap) throws IOException {
            Map<String, List<String>> map =  super.get(uri, stringListMap);
            LOGGER.info("Cop that: " + uri + " " + map);
            return map;
        }

        @Override
        public void put(URI uri, Map<String, List<String>> stringListMap) throws IOException {
            LOGGER.info("Hello sailor: " + uri + " " + stringListMap);
            super.put(uri, stringListMap);
        }
    });
    ((CookieManager)CookieHandler.getDefault()).setCookiePolicy(CookiePolicy.ACCEPT_ALL);

我只能假定存在某種“高級安全性”,旨在用於傳入的Servlet請求,但也將應用於“傳出”連接。 我找不到任何有用的weblogic部署描述符選項。

開溜。

我可能可以使它與Axis一起工作,但是id寧可讓自己用筆刺入面部。

我要回家了。


更新:好的,我還沒有解決根本原因,但是這是如何使它起作用的。 我在想是否可以訪問實際的HttpURLConnection對象,因此可以對其進行手動cookie管理。 我能夠查看Spring WS源並設置一個新的MessageSender,其工作原理基本相同。

public class MyClient extends WebServiceGatewaySupport {
    public MyClient(WebServiceMessageFactory messageFactory) {
        super(messageFactory);

        super.getWebServiceTemplate().setMessageSender(new WebServiceMessageSender() {
            @Override
            public WebServiceConnection createConnection(URI uri) throws IOException {
                URL url = uri.toURL();
                URLConnection connection = url.openConnection();
                if (!(connection instanceof HttpURLConnection)) {
                    throw new HttpTransportException("URI [" + uri + "] is not an HTTP URL");
                }
                HttpURLConnection httpURLConnection = (HttpURLConnection) connection;
                prepareConnection(httpURLConnection);

                HttpURLConnectionProxy httpURLConnectionProxy = new HttpURLConnectionProxy(url);
                httpURLConnectionProxy.setHttpURLConnection(httpURLConnection);
                httpURLConnectionProxy.setCookieManager(cookieManager);
                return new MyHttpUrlConnection(httpURLConnectionProxy);
            }

            protected void prepareConnection(HttpURLConnection connection) throws IOException {
                connection.setRequestMethod(HttpTransportConstants.METHOD_POST);
                connection.setUseCaches(false);
                connection.setDoInput(true);
                connection.setDoOutput(true);
                // ORRRRR YEAAHHHHHHH!
                cookieManager.setCookies(connection);
            }

            @Override
            public boolean supports(URI uri) {
                return true;
            }
        });
    }

另一個麻煩是我需要在調用connect()之前和之后設置和獲取cookie數據。 因此,我制作了一個HttpURLConnectionProxy類,該類將所有方法調用代理到url.openConnection()生成的方法調用中,但在connect()之后執行cookie的工作;

public void connect() throws IOException {
    httpURLConnection.connect();
    // WOOPWOOPWOOPWOOP!
    cookieManager.storeCookies(httpURLConnection);
}

但它扭曲

我認為您正在扭曲CookieManager API的預期用途。 請參考文檔CookieManager文檔 供應商的要求是維護服務器發送的會話cookie。 為了實現此要求,您需要兩個步驟:

  1. 在Spring容器中,連接一個Spring bean,其中包含方法調用CookieHandler.setDefault(new CookieManager());。
  2. 在客戶端代碼中初始化一個URI實例,該實例將標識CookieStore中的cookie

第1步

假設您使用的是Spring 3.1或更高版本,請在配置類下面找到:

@Configuration
@EnableWebMvc   // this annotation imports the class  WebMvcConfigurationSupport which bootstraps web mvc
@ComponentScan(basePackages = { "com.orgname"  })
public class WebConfig extends WebMvcConfigurerAdapter {

@Bean
public ViewResolver viewResolver() {

    InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
    viewResolver.setViewClass(JstlView.class);
    viewResolver.setPrefix("/view/jsp/");
    viewResolver.setSuffix(".jsp");
    return viewResolver;
}

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}

/**
 * This method invocation bean stands for the method call:
 * CookieHandler.setDefault(new CookieManager());
 * which should be done at the beginning of an HTTP session to bootstrap
 * the Java 6 Http state management mechanism for the application as a whole. 
 * (http://docs.oracle.com/javase/tutorial/networking/cookies/cookiehandler.html)
 * 
 */
@Bean(name="cookieHandlerSetDefaultBean") 
public MethodInvokingFactoryBean methodInvokingFactoryBean() { 
    MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean();
    methodInvokingFactoryBean.setTargetClass(CookieHandler.class);
    methodInvokingFactoryBean.setTargetMethod("setDefault");
    CookieManager cookieManager = new CookieManager();
    methodInvokingFactoryBean.setArguments(new Object[]{cookieManager}); 
    return methodInvokingFactoryBean; 
}
}

第2步

假設您的客戶端類是Spring Service或Component。 請在下面找到其代碼。

/**
 * This service aggregates the default CookieManager as explained in the API 
 * (http://docs.oracle.com/javase/6/docs/api/java/net/CookieManager.html). 
 * A system-wide CookieManager that is used by the HTTP protocol handler 
 * can be retrieved by calling CookieHandler.getDefault(). 
 * A CookieManager is initialized with aآ CookieStoreآ which manages storage
 * A CookieStore supports add(cookie) and getCookie() methods
 * A CookieStore is responsible of removing Cookie instances which have expired.
 *
 */
@Service(value="serviceConfigBean")
@DependsOn(value="cookieHandlerSetDefault")    //This is the bean initialized in the Configuration class. It is needed to be initialized before the container initializes the Service 
public class ClientCookiesStore {

    private static final Logger logger = LoggerFactory.getLogger(ClientCookiesStore.class);

    protected CookieStore inmemoryCookieStore;

    protected URI clientURI;

/**
 * The @PostConstruct (lifecycle callback method) indicates this method should be invoked after all 
 * dependency injection is complete. Thus helps in initializing any resources needed by the 
 * service.
 * 
 * In this particular initializing method:
 * (as per http://docs.oracle.com/javase/6/docs/api/java/net/CookieManager.html
 *  and http://docs.oracle.com/javase/tutorial/networking/cookies/cookiemanager.html)
 * The CookieHandler default is installed in the application via 
 * a method invoking factory bean, namely "cookieHandlerSetDefault" which 
 * exists in the java configuration file WebConfig.java

 * (1) A cookieManager property needs 2 steps setup as indicated in the code
 * (2) The internal in-memory implementation of the CookieStore interface is initialized 
 *      through the cookieManager defaults. It is assigned to the inmemoryCookieStore property.  
 * (3) Since a CookieStore aggregates many groups of cookies, each group is identified 
 *     by a URI instance. ClientCookiesStore is associated with the Client URI as indicated in 
 *     the code.  
 * 
 * @throws Exception
 */
@PostConstruct
protected void initializeBean() throws Exception {
    //      (1) Step#1 Initialize a CookieManager with the current Http session default 
    //                  which was already set in the configuration class
    CookieManager cookieManager = (CookieManager)CookieHandler.getDefault();    
    //          Step#2 Then set up the CookiePolicy.
    cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
    //      (2) Assign a CookieStore instance to the in-memory cookie store implemented by the API
    inmemoryCookieStore =  cookieManager.getCookieStore();
    //      (3) Initialize URI instance which will identify the Client cookies in the CookieStore 

    try {
        clientURI = new URI("http://vendor.webservices.com/endpoint");
    } catch (URISyntaxException e) {
        throw new Exception("URISyntaxException created while creating a URI instance for url= "+clientUrl);
    }
}

}

剩下的僅是添加新cookie和從內存存儲中檢索cookie的2種方法。 這兩種方法都屬於上述ClientCookiesStore類。

public List<HttpCookie> getCookiesList() throws Exception {
    List<HttpCookie> httpCookiesList = inmemoryCookieStore.get(clientURI);
    return httpCookiesList;
}

public void addCookie(HttpCookie newCookie) {
        inmemoryCookieStore.add(clientURI, newCookie);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM