Package com.alibaba.citrus.service.requestcontext.session.encoder

Source Code of com.alibaba.citrus.service.requestcontext.session.encoder.AbstractSerializationEncoder

/*
* Copyright 2010 Alibaba Group Holding Limited.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.alibaba.citrus.service.requestcontext.session.encoder;

import static com.alibaba.citrus.util.ArrayUtil.*;
import static com.alibaba.citrus.util.Assert.*;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Map;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;

import org.apache.commons.codec.binary.Base64;

import com.alibaba.citrus.service.requestcontext.session.SessionStore.StoreContext;
import com.alibaba.citrus.service.requestcontext.session.encrypter.Encrypter;
import com.alibaba.citrus.service.requestcontext.session.serializer.Serializer;
import com.alibaba.citrus.service.requestcontext.session.serializer.impl.HessianSerializer;
import com.alibaba.citrus.springext.support.BeanSupport;
import com.alibaba.citrus.util.io.ByteArrayOutputStream;

/**
* ͨ��<code>Serializer</code>�ṩ�����л���������������Լ������ַ�����
* <p>
* ���벽��Ϊ��
* </p>
* <ul>
* <li>��<code>Serializer</code>���л���Ĭ��ʹ��<code>HessianSerializer</code>��</li>
* <li>ѹ����</li>
* <li>���<code>Encrypter</code>���ڣ��������ܣ����򣬲����ܡ�</li>
* <li>Base64���롣</li>
* <li>URL encoding����ȷ�������ַ�������HTTP header��Ҫ��</li>
* </ul>
* <p>
* ���벽���෴��
* </p>
*
* @author Michael Zhou
*/
public abstract class AbstractSerializationEncoder extends BeanSupport implements SessionEncoder {
    protected Serializer serializer;
    protected Encrypter encrypter;

    @Override
    protected void init() throws Exception {
        if (serializer == null) {
            serializer = new HessianSerializer();
        }
    }

    /**
     * ���롣
     */
    public String encode(Map<String, Object> attrs, StoreContext storeContext) throws SessionEncoderException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        // 1. ���л�
        // 2. ѹ��
        Deflater def = new Deflater(Deflater.BEST_COMPRESSION, false);
        DeflaterOutputStream dos = new DeflaterOutputStream(baos, def);

        try {
            serializer.serialize(assertNotNull(attrs, "objectToEncode is null"), dos);
        } catch (Exception e) {
            throw new SessionEncoderException("Failed to encode session state", e);
        } finally {
            try {
                dos.close();
            } catch (IOException e) {
            }

            def.end();
        }

        byte[] plaintext = baos.toByteArray().toByteArray();

        // 3. ����
        byte[] cryptotext = encrypt(plaintext);

        // 4. base64����
        try {
            String encodedValue = new String(Base64.encodeBase64(cryptotext, false), "ISO-8859-1");

            return URLEncoder.encode(encodedValue, "ISO-8859-1");
        } catch (UnsupportedEncodingException e) {
            throw new SessionEncoderException("Failed to encode session state", e);
        }
    }

    /**
     * ���ܡ�
     */
    private byte[] encrypt(byte[] plaintext) throws SessionEncoderException {
        if (encrypter != null) {
            return encrypter.encrypt(plaintext);
        }

        return plaintext;
    }

    /**
     * ���롣
     */
    public Map<String, Object> decode(String encodedValue, StoreContext storeContext) throws SessionEncoderException {
        // 1. base64����
        byte[] cryptotext = null;

        try {
            encodedValue = URLDecoder.decode(assertNotNull(encodedValue, "encodedValue is null"), "ISO-8859-1");
            cryptotext = Base64.decodeBase64(encodedValue.getBytes("ISO-8859-1"));

            if (isEmptyArray(cryptotext)) {
                throw new SessionEncoderException("Session state is empty: " + encodedValue);
            }
        } catch (Exception e) {
            throw new SessionEncoderException("Failed to decode session state: ", e);
        }

        // 2. ����
        byte[] plaintext = decrypt(cryptotext);

        if (isEmptyArray(plaintext)) {
            throw new SessionEncoderException("Decrypted session state is empty: " + encodedValue);
        }

        // 3. ��ѹ��
        ByteArrayInputStream bais = new ByteArrayInputStream(plaintext);
        Inflater inf = new Inflater(false);
        InflaterInputStream iis = new InflaterInputStream(bais, inf);

        // 4. �����л�
        try {
            @SuppressWarnings("unchecked")
            Map<String, Object> attrs = (Map<String, Object>) serializer.deserialize(iis);
            return attrs;
        } catch (Exception e) {
            throw new SessionEncoderException("Failed to parse session state", e);
        } finally {
            try {
                iis.close();
            } catch (IOException e) {
            }

            inf.end();
        }
    }

    /**
     * ���ܡ�
     */
    private byte[] decrypt(byte[] cryptotext) throws SessionEncoderException {
        if (encrypter != null) {
            return encrypter.decrypt(cryptotext);
        }

        return cryptotext;
    }

    @Override
    public String toString() {
        return getClass().getSimpleName() + "[" + serializer + ", " + (encrypter == null ? "no encrypter" : encrypter)
                + "]";
    }
}
TOP

Related Classes of com.alibaba.citrus.service.requestcontext.session.encoder.AbstractSerializationEncoder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.