Tomcat-5.0.28是如何生成JSESSIONID ?

(Session机制原理,如果有疑问,可查找相关文献。有个博客写的也挺实用的http://justsee.iteye.com/blog/1570652)

  本人实用的Tomcat版本为5.0.28,以下内容都是针对此版本。

  产生sessionId的类是,org.apache.catalina.session.StandardManager extends ManagerBase,代码实现就在ManagerBase.generateSessionId。

  org.apache.catalina.session.ManagerBase是一个抽象类,为了方便直接进入主题,我对该类对了一些删减,只保留了方法generateSessionId相关的东东。

  下面的就是我裁剪后的代码。

/*
 * Copyright 1999,2004 The Apache Software Foundation.
 * 
 * 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 org.apache.catalina.session;


import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;


/**
 * Minimal implementation of the <b>Manager</b> interface that supports
 * no session persistence or distributable capabilities.  This class may
 * be subclassed to create more sophisticated Manager implementations.
 *
 * @author Craig R. McClanahan
 * @version $Revision: 1.27 $ $Date: 2004/05/26 16:13:59 $
 */

public class ManagerBaseTest  {
    // ----------------------------------------------------- Instance Variables

	/**
     * The default message digest algorithm to use if we cannot use
     * the requested one.
     */
    private static final String DEFAULT_ALGORITHM = "MD5";


    /**
     * The message digest algorithm to be used when generating session
     * identifiers.  This must be an algorithm supported by the
     * <code>java.security.MessageDigest</code> class on your platform.
     */
    private String algorithm = DEFAULT_ALGORITHM;

    /**
     * Return the MessageDigest implementation to be used when
     * creating session identifiers.
     */
    private MessageDigest digest = null;


    /**
     * A String initialization parameter used to increase the entropy of
     * the initialization of our random number generator.
     */
    private String entropy = null;

    /**
     * The session id length of Sessions created by this Manager.
     */
    private int sessionIdLength = 16;

    /**
     * A random number generator to use when generating session identifiers.
     */
    private Random random = null;

    /**
     * The Java class name of the random number generator class to be used
     * when generating session identifiers.
     */
    private String randomClass = "java.security.SecureRandom";


    // ------------------------------------------------------------- Properties

    /**
     * Return the entropy increaser value, or compute a semi-useful value
     * if this String has not yet been set.
     */
    public String getEntropy() {

        // Calculate a semi-useful value if this has not been set
        if (this.entropy == null)
            setEntropy(this.toString());

        return (this.entropy);

    }

    /**
     * Set the entropy increaser value.
     *
     * @param entropy The new entropy increaser value
     */
    public void setEntropy(String entropy) {
        this.entropy = entropy;
    }

    /**
     * Return the MessageDigest object to be used for calculating
     * session identifiers.  If none has been created yet, initialize
     * one the first time this method is called.
     */
    public synchronized MessageDigest getDigest() {

        if (this.digest == null) {
            long t1=System.currentTimeMillis();
            try {
                this.digest = MessageDigest.getInstance(algorithm);
            } catch (NoSuchAlgorithmException e) {
                try {
                    this.digest = MessageDigest.getInstance(DEFAULT_ALGORITHM);
                } catch (NoSuchAlgorithmException f) {
                    this.digest = null;
                }
            }
            long t2=System.currentTimeMillis();
        }

        return (this.digest);

    }

    /**
     * Return the random number generator instance we should use for
     * generating session identifiers.  If there is no such generator
     * currently defined, construct and seed a new one.
     */
    public synchronized Random getRandom() {
        if (this.random == null) {
            synchronized (this) {
                if (this.random == null) {
                    // Calculate the new random number generator seed
                    long seed = System.currentTimeMillis();
                    long t1 = seed;
                    char entropy[] = getEntropy().toCharArray();
                    for (int i = 0; i < entropy.length; i++) {
                        long update = ((byte) entropy[i]) << ((i % 8) * 8);
                        seed ^= update;
                    }
                    try {
                        // Construct and seed a new random number generator
                        Class clazz = Class.forName(randomClass);
                        this.random = (Random) clazz.newInstance();
                        this.random.setSeed(seed);
                    } catch (Exception e) {
                        // Fall back to the simple case
                        this.random = new java.util.Random();
                        this.random.setSeed(seed);
                    }
                    long t2=System.currentTimeMillis();
                }
            }
        }

        return (this.random);

    }

    protected void getRandomBytes( byte bytes[] ) {
        Random random = getRandom();
        getRandom().nextBytes(bytes);
    }


    /**
     * Generate and return a new session identifier.
     */
    public synchronized String generateSessionId() {

        byte random[] = new byte[16];

        // Render the result as a String of hexadecimal digits
        StringBuffer result = new StringBuffer();
        int resultLenBytes = 0;
        while (resultLenBytes < this.sessionIdLength) {
            getRandomBytes(random);
            random = getDigest().digest(random);
            for (int j = 0;
                    j < random.length && resultLenBytes < this.sessionIdLength;
                    j++) {
                byte b1 = (byte) ((random[j] & 0xf0) >> 4);
                byte b2 = (byte) (random[j] & 0x0f);
                if (b1 < 10)
                    result.append((char) ('0' + b1));
                else
                    result.append((char) ('A' + (b1 - 10)));
                if (b2 < 10)
                    result.append((char) ('0' + b2));
                else
                    result.append((char) ('A' + (b2 - 10)));
                resultLenBytes++;
            }
        }
        return (result.toString());

    }

	/**
	 * @Description:
	 * @param args
	 * @author mahh
	 * @since:2015-5-20 下午02:07:45
	 */
	public static void main(String[] args) {
		ManagerBaseTest managerBaseTest = new ManagerBaseTest();
		System.out.println(managerBaseTest.generateSessionId());
	}

}





郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。