Implement compression while sending hashMap over the network on Weblogic 11g server

百般思念 提交于 2019-12-13 07:05:14

问题


I have a hashMap that needs to travel from server to client over network. Now when the size increases beyond some limit provided at socket buffer the following exception is thrown.

Caused by: weblogic.socket.MaxMessageSizeExceededException: Incoming message of size: '3002880' bytes exceeds the configured maximum of: '3000000' bytes for protocol: 't3'

While googling it out I found that the socket size should be increased but that is not required as this is not such a good solution.

Then I am trying to compress the HashMap before sending using "DeflaterOutputStream/InflaterInputStream". But the challenge here is that the "ObjectOutputStream" object is created by weblogic classes and the deflater/Inflater streams are supposed to be embed while trying to create the ObjectOutputStream to make compression work.

Is there some way I can do this?

Also could there be some way to just enable the compression at t3 protocol used by weblogic to automatically use the compression. I have done some research on whether it is possible or not at t3 protocol but it seems t3 protocol does not support this. But I am not sure whether some new version of weblogic support this or not.

I was also thinking of breaking the HashMap in to the chunks of "Socket buffer size" but it will require to change the existing design and is not preferred as of now.

Please share your views thoughts on this.


回答1:


If the HashMap might contain even more data in the future, compressing it will also only be a temporary solution. The way to resolve it permanently is to split the request into several requests if there are too many items in the map.




回答2:


You could wrap the Map into another object, e.g. called Payload and make all communications be part of a compressed object.

public class Payload<T extends Serializable> {
    private T payload;
    public Payload( T payload ) {
        this.payload = payload;
    }
    private T get() {
        return payload;
    }

  public static final boolean ENABLE_COMPRESSION = BooleanUtils.toBooleanDefaultIfNull( BooleanUtils.toBooleanObject( System.getProperty( "serialization.gzip.enabled" ) ), true );

    private void writeObject( ObjectOutputStream oos ) throws IOException {
        if ( ENABLE_COMPRESSION ) {
            GZIPOutputStream zos = new GZIPOutputStream( oos, 65536 );
            ObjectOutputStream sender = new ObjectOutputStream( zos );
            sender.writeObject( payload );
            sender.flush();
            zos.finish();
        } else {
            oos.defaultWriteObject();
        }
    }

    @SuppressWarnings( "unchecked" )
    private void readObject( ObjectInputStream ois ) throws ClassNotFoundException, IOException {
        if ( ENABLE_COMPRESSION ) {
            GZIPInputStream zis = new GZIPInputStream( ois, 65536 );
            ObjectInputStream receiver = new ObjectInputStream( zis );
            payload = (T) receiver.readObject();
        } else {
            ois.defaultReadObject();
        }
    }
}

Then when sending any object, it will be sent wrapped within a Payload object and therefore compressed.

public Payload<Map> someRemoteCall() {
    Map map = new HashMap();
    populate( map ); // do whatever needs to be done to fill up the map.
    Payload<Map> payload = new Payload<Map>( map );
    return payload;
}

Obviously it may involve some changes to interfaces which may be undesirable, but so far it's the best I've found for this.

Hope this helps.



来源:https://stackoverflow.com/questions/40860275/implement-compression-while-sending-hashmap-over-the-network-on-weblogic-11g-ser

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!