@ -16,6 +16,7 @@
@@ -16,6 +16,7 @@
package org.springframework.remoting.caucho ;
import java.io.BufferedInputStream ;
import java.io.IOException ;
import java.io.InputStream ;
import java.io.OutputStream ;
@ -44,7 +45,7 @@ import org.springframework.util.CommonsLogWriter;
@@ -44,7 +45,7 @@ import org.springframework.util.CommonsLogWriter;
* < p > Hessian is a slim , binary RPC protocol .
* For information on Hessian , see the
* < a href = "http://www.caucho.com/hessian" > Hessian website < / a > .
* T his exporter requires Hessian 3 . 1 . 3 or above .
* < b > Note : As of Spring 3 . 0 , t his exporter requires Hessian 3 . 2 or above . < / b >
*
* @author Juergen Hoeller
* @since 2 . 5 . 1
@ -114,81 +115,108 @@ public class HessianExporter extends RemoteExporter implements InitializingBean
@@ -114,81 +115,108 @@ public class HessianExporter extends RemoteExporter implements InitializingBean
* /
public void invoke ( InputStream inputStream , OutputStream outputStream ) throws Throwable {
Assert . notNull ( this . skeleton , "Hessian exporter has not been initialized" ) ;
ClassLoader originalClassLoader = overrideThreadContextClassLoader ( ) ;
try {
doInvoke ( inputStream , outputStream ) ;
}
finally {
resetThreadContextClassLoader ( originalClassLoader ) ;
}
doInvoke ( this . skeleton , inputStream , outputStream ) ;
}
public void doInvoke ( final InputStream inputStream , final OutputStream outputStream ) throws Throwable {
InputStream isToUse = inputStream ;
OutputStream osToUse = outputStream ;
if ( this . debugLogger ! = null & & this . debugLogger . isDebugEnabled ( ) ) {
PrintWriter debugWriter = new PrintWriter ( new CommonsLogWriter ( this . debugLogger ) ) ;
isToUse = new HessianDebugInputStream ( inputStream , debugWriter ) ;
osToUse = new HessianDebugOutputStream ( outputStream , debugWriter ) ;
}
/ * *
* Actually invoke the skeleton with the given streams .
* @param skeleton the skeleton to invoke
* @param inputStream the request stream
* @param outputStream the response stream
* @throws Throwable if invocation failed
* /
protected void doInvoke ( HessianSkeleton skeleton , InputStream inputStream , OutputStream outputStream )
throws Throwable {
int code = isToUse . read ( ) ;
int major ;
int minor ;
ClassLoader originalClassLoader = overrideThreadContextClassLoader ( ) ;
try {
InputStream isToUse = inputStream ;
OutputStream osToUse = outputStream ;
if ( this . debugLogger ! = null & & this . debugLogger . isDebugEnabled ( ) ) {
PrintWriter debugWriter = new PrintWriter ( new CommonsLogWriter ( this . debugLogger ) ) ;
HessianDebugInputStream dis = new HessianDebugInputStream ( inputStream , debugWriter ) ;
dis . startTop2 ( ) ;
HessianDebugOutputStream dos = new HessianDebugOutputStream ( outputStream , debugWriter ) ;
dos . startTop2 ( ) ;
isToUse = dis ;
osToUse = dos ;
}
AbstractHessianInput in ;
AbstractHessianOutput out ;
if ( ! isToUse . markSupported ( ) ) {
isToUse = new BufferedInputStream ( isToUse ) ;
isToUse . mark ( 1 ) ;
}
if ( code = = 'H' ) {
major = isToUse . read ( ) ;
minor = isToUse . read ( ) ;
if ( major ! = 0x02 ) {
throw new IOException ( "Version " + major + "." + minor + " is not understood" ) ;
int code = isToUse . read ( ) ;
int major ;
int minor ;
AbstractHessianInput in ;
AbstractHessianOutput out ;
if ( code = = 'H' ) {
// Hessian 2.0 stream
major = isToUse . read ( ) ;
minor = isToUse . read ( ) ;
if ( major ! = 0x02 ) {
throw new IOException ( "Version " + major + "." + minor + " is not understood" ) ;
}
in = new Hessian2Input ( isToUse ) ;
out = new Hessian2Output ( osToUse ) ;
in . readCall ( ) ;
}
in = new Hessian2Input ( isToUse ) ;
out = new Hessian2Output ( osToUse ) ;
in . readCall ( ) ;
}
else if ( code = = 'c' ) {
major = isToUse . read ( ) ;
minor = isToUse . read ( ) ;
in = new HessianInput ( isToUse ) ;
if ( major > = 2 ) {
else if ( code = = 'C' ) {
// Hessian 2.0 call... for some reason not handled in HessianServlet!
isToUse . reset ( ) ;
in = new Hessian2Input ( isToUse ) ;
out = new Hessian2Output ( osToUse ) ;
in . readCall ( ) ;
}
else if ( code = = 'c' ) {
// Hessian 1.0 call
major = isToUse . read ( ) ;
minor = isToUse . read ( ) ;
in = new HessianInput ( isToUse ) ;
if ( major > = 2 ) {
out = new Hessian2Output ( osToUse ) ;
}
else {
out = new HessianOutput ( osToUse ) ;
}
}
else {
out = new HessianOutput ( osToUse ) ;
throw new IOException ( "Expected 'H'/'C' (Hessian 2.0) or 'c' (Hessian 1.0) in hessian input at " + cod e) ;
}
}
else {
throw new IOException ( "Expected 'H' (Hessian 2.0) or 'c' (Hessian 1.0) in hessian input at " + code ) ;
}
if ( this . serializerFactory ! = null ) {
in . setSerializerFactory ( this . serializerFactory ) ;
out . setSerializerFactory ( this . serializerFactory ) ;
}
try {
this . skeleton . invoke ( in , out ) ;
}
finally {
try {
in . close ( ) ;
isToUse . close ( ) ;
}
catch ( IOException ex ) {
// ignore
if ( this . serializerFactory ! = null ) {
in . setSerializerFactory ( this . serializerFactory ) ;
out . setSerializerFactory ( this . serializerFactory ) ;
}
try {
out . close ( ) ;
osToUse . close ( ) ;
skeleton . invoke ( in , out ) ;
}
catch ( IOException ex ) {
// ignore
finally {
try {
in . close ( ) ;
isToUse . close ( ) ;
}
catch ( IOException ex ) {
// ignore
}
try {
out . close ( ) ;
osToUse . close ( ) ;
}
catch ( IOException ex ) {
// ignore
}
}
}
finally {
resetThreadContextClassLoader ( originalClassLoader ) ;
}
}
}