Cette page présente le code pour activer la compression GZip sous JBoss 4.
Classe info.jtips.jboss.GzHttpInvoker
package info.jtips.jboss;
import javax.management.ObjectName;
import org.jboss.invocation.Invoker;
import org.jboss.system.Registry;
public class GzHttpInvoker extends org.jboss.invocation.http.server.HttpInvoker {
protected void startService() throws Exception {
checkInvokerURL();
// AH Modification Alexis Hassler
// => instantiation de GzHttpInvokerProxy
Invoker delegateInvoker = new GzHttpInvokerProxy(getInvokerURL());
// Export the Invoker interface
ObjectName name = super.getServiceName();
Registry.bind(name, delegateInvoker);
log.debug("Bound Http invoker for JMX node");
}
}
Classe info.jtips.jboss.GzHttpInvokerProxy
package info.jtips.jboss;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.HttpURLConnection;
import java.rmi.ServerException;
import org.jboss.invocation.Invocation;
import org.jboss.invocation.InvocationException;
import org.jboss.invocation.MarshalledInvocation;
import org.jboss.invocation.http.interfaces.Util;
public class GzHttpInvokerProxy
extends org.jboss.invocation.http.interfaces.HttpInvokerProxy {
public GzHttpInvokerProxy() {
super();
}
public GzHttpInvokerProxy(String externalURLValue) {
super(externalURLValue);
}
public Object invoke(Invocation invocation) throws Exception {
// We are going to go through a Remote invocation, switch to a
// Marshalled Invocation
MarshalledInvocation mi = new MarshalledInvocation(invocation);
if (externalURL == null)
externalURL = Util.resolveURL(externalURLValue);
try {
// AH Modification Alexis Hassler => utilisation de GzHttpUtil
Object value = GzHttpUtil.invoke(externalURL, mi);
return value;
} catch (InvocationException e) {
// Unwrap the invoker servlet InvocationExceptions
Throwable t = e.getTargetException();
if (t instanceof Exception)
throw (Exception) t;
else if (t instanceof Error)
throw (Error) t;
throw new InvocationTargetException(t);
} catch (IOException e) {
throw new ServerException("IOE", e);
}
}
}
Classe info.jtips.jboss.GzHttpUtil
package info.jtips.jboss;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectStreamException;
import java.io.OutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.Authenticator;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.PrivilegedAction;
import java.security.AccessController;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;
import org.jboss.invocation.Invocation;
import org.jboss.invocation.InvocationException;
import org.jboss.invocation.MarshalledValue;
import org.jboss.invocation.http.interfaces.AnyhostVerifier;
import org.jboss.invocation.http.interfaces.Util;
import org.jboss.logging.Logger;
import org.jboss.security.SecurityAssociationAuthenticator;
import org.jboss.net.ssl.SSLSocketFactoryBuilder;
public class GzHttpUtil {
private static String REQUEST_CONTENT_TYPE =
"application/x-java-serialized-object;" +
"class=org.jboss.invocation.MarshalledInvocation";
// AH Ajout Alexis Hassler => autoriser le compression
private static String REQUEST_ACCEPT_ENCODING = "multipart/x-gzip";
private static Logger log = Logger.getLogger(GzHttpUtil.class);
/ A custom SSLSocketFactory builder to use for https connections /
private static SSLSocketFactoryBuilder sslSocketFactoryBuilder;
static class SetAuthenticator implements PrivilegedAction {
public Object run() {
Authenticator.setDefault(new SecurityAssociationAuthenticator());
return null;
}
}
static class ReadSSLBuilder implements PrivilegedAction {
public Object run() {
String value = System.getProperty(Util.SSL_FACTORY_BUILDER);
return value;
}
}
static {
// Install the java.net.Authenticator to use
try {
SetAuthenticator action = new SetAuthenticator();
AccessController.doPrivileged(action);
} catch (Exception e) {
log.warn("Failed to install SecurityAssociationAuthenticator", e);
}
ClassLoader loader = Thread.currentThread().getContextClassLoader();
String factoryFactoryFQCN = null;
try {
ReadSSLBuilder action = new ReadSSLBuilder();
factoryFactoryFQCN =
(String) AccessController.doPrivileged(action);
} catch (Exception e) {
log.warn("Failed to read " + Util.SSL_FACTORY_BUILDER, e);
}
if (factoryFactoryFQCN != null) {
try {
Class clazz = loader.loadClass(factoryFactoryFQCN);
sslSocketFactoryBuilder = (SSLSocketFactoryBuilder) clazz
.newInstance();
} catch (Exception e) {
log.warn("Could not instantiate SSLSocketFactoryFactory", e);
}
}
}
/
* Post the Invocation as a serialized MarshalledInvocation object.
* This is using the URL class for now but this should be improved to
* a cluster aware layer with full usage of HTTP 1.1 features, pooling,
* etc.
*/
public static Object invoke(URL externalURL, Invocation mi)
throws Exception {
if (log.isTraceEnabled())
log.trace("invoke, externalURL=" + externalURL);
/
* Post the MarshalledInvocation data. This is using the URL class for
* now but this should be improved to a cluster aware layer with full
* usage of HTTP 1.1 features, pooling, etc.
*/
HttpURLConnection conn = (HttpURLConnection) externalURL
.openConnection();
Util.configureHttpsHostVerifier(conn);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestProperty("ContentType", REQUEST_CONTENT_TYPE);
// AH Ajout Alexis Hassler => autoriser le compression
conn.setRequestProperty("Accept-Encoding", REQUEST_ACCEPT_ENCODING);
conn.setRequestMethod("POST");
OutputStream os = conn.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
// Fin Ajout Alexis Hassler
try {
oos.writeObject(mi);
oos.flush();
} catch (ObjectStreamException e) {
// This generally represents a programming/deployment error,
// not a communication problem
throw new InvocationException(e);
}
// Get the response MarshalledValue object
InputStream is = conn.getInputStream();
// AH Ajout Alexis Hassler => Stream de décompression
GZIPInputStream gzis = new GZIPInputStream(is);
ObjectInputStream ois = new ObjectInputStream(gzis);
// ObjectInputStream ois = new ObjectInputStream(is);
// Fin Ajout Alexis Hassler
MarshalledValue mv = (MarshalledValue) ois.readObject();
// A hack for jsse connection pooling (see patch ).
ois.read();
ois.close();
oos.close();
// If the encoded value is an exception throw it
Object value = mv.get();
if (value instanceof Exception) {
throw (Exception) value;
}
return value;
}
}