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