Announcement Announcement Module
Collapse
No announcement yet.
Apache Component's HttpClient as spring bean Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Apache Component's HttpClient as spring bean

    Hi guys, is it okay if I declare HttpClient from apache components as spring bean? The usual way was to create a new HttpClient() everytime to make connection and then close the connection by httpClient.getConnectionManager().shutdown(), but in my case, since I declare it as bean, I just have another bean to use this httpClient bean via injection and make connection without shutting it down later (coz after shutting down, the bean is dead, and cant work for next connection).

    I am just wondering if this will be thread safe or is there any other problem?


    Thanks in advance.

  • #2
    android21,

    I doubt using an HttpClient directly from a bean is safe, much less thread safe; instead, you should probably make a MultiThreadedHttpConnectionManager bean, inject that into your classes and perform something like the following snippet when you need a new client.

    Code:
    HttpClient client = new HttpClient(connectionManager);
    Alternatively, and probably a better idea, write a HttpClientFactory class to instantiate a new HttpClient for you; if you absolutely must use it the HttpClient as a bean.

    According to the HttpClient docs, using a connection manager is really the only way to guarantee the thread safety; but that's something you'd probably want to hit their forums for :-)

    Hope that helps,

    Comment


    • #3
      Alternatively, and probably a better idea, write a HttpClientFactory class to instantiate a new HttpClient for you; if you absolutely must use it the HttpClient as a bean.
      By that you mean, I just create a Class with static method to return HttpClient?

      Like: public static getHttpClient() ?

      is this going to be thread safe?

      Many Thanks.

      Comment


      • #4
        android21,

        Well, in simpler terms, to be thread safe, you should inject a shared connection manager, not a client (unless you go the factory route which would probably be more work than its worth). You can search and read up on making a factory or factory like method to perform these steps and get a new client from your app context, or more easily, just use something sort of like this method which I've used in the past and that scaled pretty well and was thread-safe.

        bean XML
        Code:
            <bean id="connectionManager" class="org.apache.commons.httpclient.MultiThreadedHttpConnectionManager">
                <property name="maxConnectionsPerHost" value="5" />
                <property name="maxTotalConnections" value="1000" />
            </bean>
        
            <bean id="mySpecialClass" class="MySpecialClass">
                <property name="connectionManager" ref="connectionManager" />
            </bean>
        and Java like
        Code:
        /**
         * My Special Class
         *
         * @author Joshua Preston <[email protected]>
         */
        public class MySpecialClass {
        
            private HttpConnectionManager connectionManager;
        
            public MySpecialClass() {
                super();
            }
        
            public void setConnectionManager(HttpConnectionManager connectionManager) {
                this.connectionManager = connectionManager;
            }
        
            public void doSomethingHttpClientRelated() {
                HttpClient client = new HttpClient(connectionManager);
        
                // and then from inside some thread executing a method
                GetMethod get = new GetMethod("http://httpcomponents.apache.org/");
                try {
                    client.executeMethod(get);
                    // print response to stdout
                    System.out.println(get.getResponseBodyAsStream());
                } finally {
                    // be sure the connection is released back to the connection 
                    // manager
                    get.releaseConnection();
                }
        
            }
        }
        I based this on what the http client docs have to say about threading, located at http://hc.apache.org/httpclient-3.x/threading.html.

        Hope that helps,

        Comment


        • #5
          Thanks for your help joshua, I am creating HttpClient as spring bean, because I am trying to work it out with Jmock, and it seems not working... Just wondering why will it be not thread-safe if we declare it as spring bean and just inject it into a class?

          Comment


          • #6
            android21,

            From http://hc.apache.org/httpclient-3.x/performance.html

            HttpClient is fully thread-safe when used with a thread-safe connection manager such as MultiThreadedHttpConnectionManager. Please note that each respective thread of execution must have a local instance of HttpMethod and can have a local instance of HttpState or/and HostConfiguration to represent a specific host configuration and conversational state. At the same time the HttpClient instance and connection manager should be shared among all threads for maximum efficiency.
            Apparently you can share a single HttpClient as a bean, just make sure you're sharing the multi threaded http connection manager along with it.

            Hope that helps,

            Comment


            • #7
              Thanks, I guess I will just try that...

              Comment

              Working...
              X