1 16 17 package org.springframework.remoting.httpinvoker; 18 19 import java.io.ByteArrayOutputStream ; 20 import java.io.IOException ; 21 import java.io.InputStream ; 22 import java.io.ObjectInputStream ; 23 import java.io.ObjectOutputStream ; 24 import java.io.OutputStream ; 25 import java.rmi.RemoteException ; 26 27 import org.apache.commons.logging.Log; 28 import org.apache.commons.logging.LogFactory; 29 30 import org.springframework.beans.factory.BeanClassLoaderAware; 31 import org.springframework.remoting.rmi.CodebaseAwareObjectInputStream; 32 import org.springframework.remoting.support.RemoteInvocation; 33 import org.springframework.remoting.support.RemoteInvocationResult; 34 import org.springframework.util.Assert; 35 36 46 public abstract class AbstractHttpInvokerRequestExecutor 47 implements HttpInvokerRequestExecutor, BeanClassLoaderAware { 48 49 52 public static final String CONTENT_TYPE_SERIALIZED_OBJECT = "application/x-java-serialized-object"; 53 54 55 protected static final String HTTP_METHOD_POST = "POST"; 56 57 protected static final String HTTP_HEADER_CONTENT_TYPE = "Content-Type"; 58 59 protected static final String HTTP_HEADER_CONTENT_LENGTH = "Content-Length"; 60 61 protected static final String HTTP_HEADER_ACCEPT_ENCODING = "Accept-Encoding"; 62 63 protected static final String HTTP_HEADER_CONTENT_ENCODING = "Content-Encoding"; 64 65 protected static final String ENCODING_GZIP = "gzip"; 66 67 68 private static final int SERIALIZED_INVOCATION_BYTE_ARRAY_INITIAL_SIZE = 1024; 69 70 71 protected final Log logger = LogFactory.getLog(getClass()); 72 73 private String contentType = CONTENT_TYPE_SERIALIZED_OBJECT; 74 75 private boolean acceptGzipEncoding = true; 76 77 private ClassLoader beanClassLoader; 78 79 80 84 public void setContentType(String contentType) { 85 Assert.notNull(contentType, "'contentType' must not be null"); 86 this.contentType = contentType; 87 } 88 89 92 public String getContentType() { 93 return this.contentType; 94 } 95 96 102 public void setAcceptGzipEncoding(boolean acceptGzipEncoding) { 103 this.acceptGzipEncoding = acceptGzipEncoding; 104 } 105 106 110 public boolean isAcceptGzipEncoding() { 111 return this.acceptGzipEncoding; 112 } 113 114 public void setBeanClassLoader(ClassLoader classLoader) { 115 this.beanClassLoader = classLoader; 116 } 117 118 121 protected ClassLoader getBeanClassLoader() { 122 return this.beanClassLoader; 123 } 124 125 126 public final RemoteInvocationResult executeRequest( 127 HttpInvokerClientConfiguration config, RemoteInvocation invocation) throws Exception { 128 129 ByteArrayOutputStream baos = getByteArrayOutputStream(invocation); 130 if (logger.isDebugEnabled()) { 131 logger.debug("Sending HTTP invoker request for service at [" + config.getServiceUrl() + 132 "], with size " + baos.size()); 133 } 134 return doExecuteRequest(config, baos); 135 } 136 137 143 protected ByteArrayOutputStream getByteArrayOutputStream(RemoteInvocation invocation) throws IOException { 144 ByteArrayOutputStream baos = new ByteArrayOutputStream (SERIALIZED_INVOCATION_BYTE_ARRAY_INITIAL_SIZE); 145 writeRemoteInvocation(invocation, baos); 146 return baos; 147 } 148 149 162 protected void writeRemoteInvocation(RemoteInvocation invocation, OutputStream os) throws IOException { 163 ObjectOutputStream oos = new ObjectOutputStream (decorateOutputStream(os)); 164 try { 165 doWriteRemoteInvocation(invocation, oos); 166 oos.flush(); 167 } 168 finally { 169 oos.close(); 170 } 171 } 172 173 181 protected OutputStream decorateOutputStream(OutputStream os) throws IOException { 182 return os; 183 } 184 185 196 protected void doWriteRemoteInvocation(RemoteInvocation invocation, ObjectOutputStream oos) throws IOException { 197 oos.writeObject(invocation); 198 } 199 200 201 215 protected abstract RemoteInvocationResult doExecuteRequest( 216 HttpInvokerClientConfiguration config, ByteArrayOutputStream baos) 217 throws Exception ; 218 219 235 protected RemoteInvocationResult readRemoteInvocationResult(InputStream is, String codebaseUrl) 236 throws IOException , ClassNotFoundException { 237 238 ObjectInputStream ois = createObjectInputStream(decorateInputStream(is), codebaseUrl); 239 try { 240 return doReadRemoteInvocationResult(ois); 241 } 242 finally { 243 ois.close(); 244 } 245 } 246 247 255 protected InputStream decorateInputStream(InputStream is) throws IOException { 256 return is; 257 } 258 259 273 protected ObjectInputStream createObjectInputStream(InputStream is, String codebaseUrl) throws IOException { 274 return new CodebaseAwareObjectInputStream(is, getBeanClassLoader(), codebaseUrl); 275 } 276 277 288 protected RemoteInvocationResult doReadRemoteInvocationResult(ObjectInputStream ois) 289 throws IOException , ClassNotFoundException { 290 291 Object obj = ois.readObject(); 292 if (!(obj instanceof RemoteInvocationResult)) { 293 throw new RemoteException ("Deserialized object needs to be assignable to type [" + 294 RemoteInvocationResult.class.getName() + "]: " + obj); 295 } 296 return (RemoteInvocationResult) obj; 297 } 298 299 } 300 | Popular Tags |