views:

41

answers:

2

I've been poking around the org.springframework.remoting.httpinvoker package in Spring 2.5 trying to find a way to get visibility into the size of the response, but I keep going around in circles.

Via another question I saw here, I think what I want to do is get a handle on the InputStream that represents the response from the server, and then wrap it with an Apache commons-io CountingInputStream. What's the best way to go about doing this?

For the moment, I'd be happy with just printing the size of the response to stdout, but eventually I want to store it in a well-known location in my app for optional display.

+1  A: 

You're thinking along the right lines, it just needs fleshing out with specifics. Brace yourself, I'm going to hit you with a bunch of long class names...

The client-side factory that generates the stub that talks to the remote service is HttpInvokerProxyFactoryBean. The superclass (HttpInvokerClientInterceptor) has a property called httpInvokerRequestExecutor, which defaults to an instance of SimpleHttpInvokerRequestExecutor.

This is ripe for subclassing and extending; specifically it has a decorateInputStream method which you can use:

public class CountingHttpInvokerRequestExecutor extends SimpleHttpInvokerRequestExecutor {
   @Override
   protected InputStream decorateInputStream(InputStream is) throws IOException {
      return new CountingInputStream(super.decorateInputStream(is));
   }
}

And then inject that into the proxy factory:

<bean class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
    <property name="httpInvokerRequestExecutor">
        <bean class="com.mycompany.CountingHttpInvokerRequestExecutor"/>
    </property>
      <!-- Plus the various other properties required by HttpInvokerProxyFactoryBean  -->
      <!-- URL, proxy interface, etc -->
</bean>

The trick then becomes to get hold of that information, which will require some creative rewiring. You could, for example, obtain the new instances of CountingInputStream from another factory somewhere, which would then expose the byte count to your user interface.

skaffman
Hmm, someone's been mucking about with the code formatting on SO.... not an improvement...
skaffman
Yeah, that "trick" is sort of the nut of the problem that I've been going around in my head about. I was trying to get it via override invoke() in an overridden HttpInvokerProxyFactoryBean, but because of protected methods was not able to do that cleanly.
aarestad
A: 

The above was most of what I needed to do to get the Input/OutputStreams wired up. The last step to actually report the information involved overriding the commons-io CountingStreams' close() method to simply report the total bytes read/written during that session. I print that out using the log, and there we go! This has the drawback of not being able to match up the size to a particular service call, but perhaps some further overriding to the SimpleHttpInvokerRequestExecutor could add some further logging, though this would require the logging occurred synchronously, which is a dubious assumption.

aarestad