【序列化】Java中将使用PHP序列化工具将数据序列化

版权声明:整理不易,转载请注明出处。 https://blog.csdn.net/linmengmeng_1314/article/details/86498683

在项目中需要和PHP公用一个MySQL数据库,有些数据需要序列化之后保存,这就需要将待存储的数据序列化之后存到数据库中,取出的时候,需要反序列化之后才能正常使用。
原数据:

{"06008816930683722.jpg", "06008816930681525.jpg"}

数据库中存的数据是这样的:

a:1:{s:5:"buyer";a:2:{i:1;s:21:"06008816930683722.jpg";i:2;s:21:"06008816930681525.jpg";}}

首先是借助一个PHP的序列化工具:

		<dependency>
			<groupId>org.sction</groupId>
			<artifactId>phprpc</artifactId>
			<version>3.0.2</version>
		</dependency>

PHPSerializer.java

package com.thinkgem.jeesite.common.utils;

import java.io.*;
import java.util.*;
import java.lang.reflect.*;

import org.lorecraft.phparser.SerializedPhpParser;

/**
 * Description:
 * 
 * @author : ss Shi
 * @date :2016-4-12 下午1:27:06
 */

class UnSerializeResult {
    public Object value;
    public int hv;
    public UnSerializeResult() {}
    public UnSerializeResult(Object value, int hv) {
        this.value = value;
        this.hv = hv;
    }
}
public class PHPSerializer {
	private static Package[] __packages = Package.getPackages();
	private static final byte __Quote = 34;
	private static final byte __0 = 48;
	private static final byte __1 = 49;
	private static final byte __Colon = 58;
	private static final byte __Semicolon = 59;
	private static final byte __C = 67;
	private static final byte __N = 78;
	private static final byte __O = 79;
	private static final byte __R = 82;
	private static final byte __U = 85;
	private static final byte __Slash = 92;
	private static final byte __a = 97;
	private static final byte __b = 98;
	private static final byte __d = 100;
	private static final byte __i = 105;
	private static final byte __r = 114;
	private static final byte __s = 115;
	private static final byte __LeftB = 123;
	private static final byte __RightB = 125;
	private static final String __NAN = new String("NAN");
	private static final String __INF = new String("INF");
	private static final String __NINF = new String("-INF");

	private PHPSerializer() {
	}

	public static byte[] serialize(Object obj) {
		return serialize(obj, "UTF-8");
	}

	public static byte[] serialize(Object obj, String charset) {
		HashMap ht = new HashMap();
		int hv = 1;
		ByteArrayOutputStream stream = new ByteArrayOutputStream();

		hv = serialize(stream, obj, ht, hv, charset);
		byte[] result = stream.toByteArray();

		try {
			stream.close();
		} catch (Exception e) {
		}
		return result;
	}

	public static int serialize(ByteArrayOutputStream stream, Object obj,
			HashMap ht, int hv, String charset) {
		if (obj == null) {
			hv++;
			writeNull(stream);
		} else {
			if (obj instanceof Boolean) {
				hv++;
				writeBoolean(stream, ((Boolean) obj).booleanValue() ? __1 : __0);
			} else if ((obj instanceof Byte) || (obj instanceof Short)
					|| (obj instanceof Integer)) {
				hv++;
				writeInteger(stream, getBytes(obj));
			} else if (obj instanceof Long) {
				hv++;
				writeDouble(stream, getBytes(obj));
			} else if (obj instanceof Float) {
				hv++;
				Float f = (Float) obj;

				if (f.isNaN()) {
					writeDouble(stream, getBytes(__NAN));
				} else if (f.isInfinite()) {
					if (f.floatValue() > 0) {
						writeDouble(stream, getBytes(__INF));
					} else {
						writeDouble(stream, getBytes(__NINF));
					}
				} else {
					writeDouble(stream, getBytes(f));
				}
			} else if (obj instanceof Double) {
				hv++;
				Double d = (Double) obj;

				if (d.isNaN()) {
					writeDouble(stream, getBytes(__NAN));
				} else if (d.isInfinite()) {
					if (d.doubleValue() > 0) {
						writeDouble(stream, getBytes(__INF));
					} else {
						writeDouble(stream, getBytes(__NINF));
					}
				} else {
					writeDouble(stream, getBytes(d));
				}
			} else if ((obj instanceof Character) || (obj instanceof String)) {
				hv++;
				writeString(stream, getBytes(obj, charset));
			} else if (obj.getClass().isArray()) {
				if (ht.containsKey(new Integer(obj.hashCode()))) {
					writePointRef(stream,
							getBytes(ht.get(new Integer(obj.hashCode()))));
				} else {
					ht.put(new Integer(obj.hashCode()), new Integer(hv++));
					hv = writeArray(stream, obj, ht, hv, charset);
				}
			} else if (obj instanceof ArrayList) {
				if (ht.containsKey(new Integer(obj.hashCode()))) {
					writePointRef(stream,
							getBytes(ht.get(new Integer(obj.hashCode()))));
				} else {
					ht.put(new Integer(obj.hashCode()), new Integer(hv++));
					hv = writeArrayList(stream, (ArrayList) obj, ht, hv,
							charset);
				}
			} else if (obj instanceof HashMap) {
				if (ht.containsKey(new Integer(obj.hashCode()))) {
					writePointRef(stream,
							getBytes(ht.get(new Integer(obj.hashCode()))));
				} else {
					ht.put(new Integer(obj.hashCode()), new Integer(hv++));
					hv = writeHashMap(stream, (HashMap) obj, ht, hv, charset);
				}
			} else {
				if (ht.containsKey(new Integer(obj.hashCode()))) {
					hv++;
					writeRef(stream,
							getBytes(ht.get(new Integer(obj.hashCode()))));
				} else {
					ht.put(new Integer(obj.hashCode()), new Integer(hv++));
					hv = writeObject(stream, obj, ht, hv, charset);
				}
			}
		}
		return hv;
	}

	private static void writeNull(ByteArrayOutputStream stream) {
		stream.write(__N);
		stream.write(__Semicolon);
	}

	private static void writeRef(ByteArrayOutputStream stream, byte[] r) {
		stream.write(__r);
		stream.write(__Colon);
		stream.write(r, 0, r.length);
		stream.write(__Semicolon);
	}

	private static void writePointRef(ByteArrayOutputStream stream, byte[] p) {
		stream.write(__R);
		stream.write(__Colon);
		stream.write(p, 0, p.length);
		stream.write(__Semicolon);
	}

	private static void writeBoolean(ByteArrayOutputStream stream, byte b) {
		stream.write(__b);
		stream.write(__Colon);
		stream.write(b);
		stream.write(__Semicolon);
	}

	private static void writeInteger(ByteArrayOutputStream stream, byte[] i) {
		stream.write(__i);
		stream.write(__Colon);
		stream.write(i, 0, i.length);
		stream.write(__Semicolon);
	}

	private static void writeDouble(ByteArrayOutputStream stream, byte[] d) {
		stream.write(__d);
		stream.write(__Colon);
		stream.write(d, 0, d.length);
		stream.write(__Semicolon);
	}

	private static void writeString(ByteArrayOutputStream stream, byte[] s) {
		byte[] slen = getBytes(new Integer(s.length));

		stream.write(__s);
		stream.write(__Colon);
		stream.write(slen, 0, slen.length);
		stream.write(__Colon);
		stream.write(__Quote);
		stream.write(s, 0, s.length);
		stream.write(__Quote);
		stream.write(__Semicolon);
	}

	private static int writeArray(ByteArrayOutputStream stream, Object a,
			HashMap ht, int hv, String charset) {
		int len = Array.getLength(a);
		byte[] alen = getBytes(new Integer(len));

		stream.write(__a);
		stream.write(__Colon);
		stream.write(alen, 0, alen.length);
		stream.write(__Colon);
		stream.write(__LeftB);
		for (int i = 0; i < len; i++) {
			writeInteger(stream, getBytes(new Integer(i)));
			hv = serialize(stream, Array.get(a, i), ht, hv, charset);
		}
		stream.write(__RightB);
		return hv;
	}

	private static int writeArrayList(ByteArrayOutputStream stream,
			ArrayList a, HashMap ht, int hv, String charset) {
		int len = a.size();
		byte[] alen = getBytes(new Integer(len));

		stream.write(__a);
		stream.write(__Colon);
		stream.write(alen, 0, alen.length);
		stream.write(__Colon);
		stream.write(__LeftB);
		for (int i = 0; i < len; i++) {
			writeInteger(stream, getBytes(new Integer(i)));
			hv = serialize(stream, a.get(i), ht, hv, charset);
		}
		stream.write(__RightB);
		return hv;
	}

	private static int writeHashMap(ByteArrayOutputStream stream, HashMap h,
			HashMap ht, int hv, String charset) {
		int len = h.size();
		byte[] hlen = getBytes(new Integer(len));

		stream.write(__a);
		stream.write(__Colon);
		stream.write(hlen, 0, hlen.length);
		stream.write(__Colon);
		stream.write(__LeftB);
		for (Iterator keys = h.keySet().iterator(); keys.hasNext();) {
			Object key = keys.next();

			if ((key instanceof Byte) || (key instanceof Short)
					|| (key instanceof Integer)) {
				writeInteger(stream, getBytes(key));
			} else if (key instanceof Boolean) {
				writeInteger(
						stream,
						new byte[] { ((Boolean) key).booleanValue() ? __1 : __0 });
			} else {
				writeString(stream, getBytes(key, charset));
			}
			hv = serialize(stream, h.get(key), ht, hv, charset);
		}
		stream.write(__RightB);
		return hv;
	}

	private static int writeObject(ByteArrayOutputStream stream, Object obj,
			HashMap ht, int hv, String charset) {
		Class cls = obj.getClass();

		if (obj instanceof java.io.Serializable) {
			byte[] className = getBytes(getClassName(cls), charset);
			byte[] classNameLen = getBytes(new Integer(className.length));

			if (obj instanceof org.phprpc.util.Serializable) {
				byte[] cs = ((org.phprpc.util.Serializable) obj).serialize();
				byte[] cslen = getBytes(new Integer(cs.length));

				stream.write(__C);
				stream.write(__Colon);
				stream.write(classNameLen, 0, classNameLen.length);
				stream.write(__Colon);
				stream.write(__Quote);
				stream.write(className, 0, className.length);
				stream.write(__Quote);
				stream.write(__Colon);
				stream.write(cslen, 0, cslen.length);
				stream.write(__Colon);
				stream.write(__LeftB);
				stream.write(cs, 0, cs.length);
				stream.write(__RightB);
			} else {
				Method __sleep;

				try {
					__sleep = cls.getMethod("__sleep", new Class[0]);
				} catch (Exception e) {
					__sleep = null;
				}
				int fl = 0;
				Field[] f;

				if (__sleep != null) {
					String[] fieldNames;

					try {
						__sleep.setAccessible(true);
						fieldNames = (String[]) __sleep.invoke(obj,
								new Object[0]);
					} catch (Exception e) {
						fieldNames = null;
					}
					f = getFields(obj, fieldNames);
				} else {
					f = getFields(obj);
				}
				AccessibleObject.setAccessible(f, true);
				byte[] flen = getBytes(new Integer(f.length));

				stream.write(__O);
				stream.write(__Colon);
				stream.write(classNameLen, 0, classNameLen.length);
				stream.write(__Colon);
				stream.write(__Quote);
				stream.write(className, 0, className.length);
				stream.write(__Quote);
				stream.write(__Colon);
				stream.write(flen, 0, flen.length);
				stream.write(__Colon);
				stream.write(__LeftB);
				for (int i = 0, len = f.length; i < len; i++) {
					int mod = f[i].getModifiers();

					if (Modifier.isPublic(mod)) {
						writeString(stream, getBytes(f[i].getName(), charset));
					} else if (Modifier.isProtected(mod)) {
						writeString(stream,
								getBytes("*" + f[i].getName(), charset));
					} else {
						writeString(
								stream,
								getBytes(
										""
												+ getClassName(f[i]
														.getDeclaringClass())
												+ "" + f[i].getName(), charset));
					}
					Object o;

					try {
						o = f[i].get(obj);
					} catch (Exception e) {
						o = null;
					}
					hv = serialize(stream, o, ht, hv, charset);
				}
				stream.write(__RightB);
			}
		} else {
			writeNull(stream);
		}
		return hv;
	}

	private static byte[] getBytes(Object obj) {
		try {
			return obj.toString().getBytes("US-ASCII");
		} catch (Exception e) {
			return obj.toString().getBytes();
		}
	}

	private static byte[] getBytes(Object obj, String charset) {
		try {
			return obj.toString().getBytes(charset);
		} catch (Exception e) {
			return obj.toString().getBytes();
		}
	}

	private static String getString(byte[] data, String charset) {
		try {
			return new String(data, charset);
		} catch (Exception e) {
			return new String(data);
		}
	}

	private static Class getClass(String className) {
		try {
			Class cls = Class.forName(className);

			return cls;
		} catch (Exception e) {
		}
		for (int i = 0; i < __packages.length; i++) {
			try {
				Class cls = Class.forName(__packages[i].getName() + "."
						+ className);

				return cls;
			} catch (Exception e) {
			}
		}
		return null;
	}

	private static String getClassName(Class cls) {
		return cls.getName().substring(cls.getPackage().getName().length() + 1);
	}

	private static Field getField(Object obj, String fieldName) {
		Class cls = obj.getClass();

		while (cls != null) {
			try {
				Field result = cls.getDeclaredField(fieldName);
				int mod = result.getModifiers();

				if (Modifier.isFinal(mod) || Modifier.isStatic(mod)) {
					return null;
				}
				return result;
			} catch (Exception e) {
			}
			cls = cls.getSuperclass();
		}
		return null;
	}

	private static Field[] getFields(Object obj, String[] fieldNames) {
		if (fieldNames == null) {
			return getFields(obj);
		}
		int n = fieldNames.length;
		ArrayList fields = new ArrayList(n);

		for (int i = 0; i < n; i++) {
			Field f = getField(obj, fieldNames[i]);

			if (f != null) {
				fields.add(f);
			}
		}
		return (Field[]) fields.toArray(new Field[0]);
	}

	private static Field[] getFields(Object obj) {
		ArrayList fields = new ArrayList();
		Class cls = obj.getClass();

		while (cls != null) {
			Field[] fs = cls.getDeclaredFields();

			for (int i = 0; i < fs.length; i++) {
				int mod = fs[i].getModifiers();

				if (!Modifier.isFinal(mod) && !Modifier.isStatic(mod)) {
					fields.add(fs[i]);
				}
			}
			cls = cls.getSuperclass();
		}
		return (Field[]) fields.toArray(new Field[0]);
	}

	public static Object newInstance(Class cls) {
		try {
			Constructor ctor = cls.getConstructor(new Class[0]);
			int mod = ctor.getModifiers();

			if (Modifier.isPublic(mod)) {
				return ctor.newInstance(new Object[0]);
			}
		} catch (Exception e) {
		}
		try {
			Constructor ctor = cls.getConstructor(new Class[] { Integer.TYPE });
			int mod = ctor.getModifiers();

			if (Modifier.isPublic(mod)) {
				return ctor.newInstance(new Object[] { new Integer(0) });
			}
		} catch (Exception e) {
		}
		try {
			Constructor ctor = cls.getConstructor(new Class[] { Boolean.TYPE });
			int mod = ctor.getModifiers();

			if (Modifier.isPublic(mod)) {
				return ctor.newInstance(new Object[] { new Boolean(false) });
			}
		} catch (Exception e) {
		}
		try {
			Constructor ctor = cls.getConstructor(new Class[] { String.class });
			int mod = ctor.getModifiers();

			if (Modifier.isPublic(mod)) {
				return ctor.newInstance(new Object[] { "" });
			}
		} catch (Exception e) {
		}
		Field[] f = cls.getFields();

		for (int i = 0; i < f.length; i++) {
			if (f[i].getType() == cls && Modifier.isStatic(f[i].getModifiers())) {
				try {
					return f[i].get(null);
				} catch (Exception e) {
				}
			}
		}
		Method[] m = cls.getMethods();

		for (int i = 0; i < m.length; i++) {
			if (m[i].getReturnType() == cls
					&& Modifier.isStatic(m[i].getModifiers())) {
				try {
					return m[i].invoke(null, new Object[0]);
				} catch (Exception e) {
				}
				try {
					return m[i].invoke(null, new Object[] { new Integer(0) });
				} catch (Exception e) {
				}
				try {
					return m[i].invoke(null,
							new Object[] { new Boolean(false) });
				} catch (Exception e) {
				}
				try {
					return m[i].invoke(null, new Object[] { "" });
				} catch (Exception e) {
				}
			}
		}
		return null;
	}

	public static Number cast(Number n, Class destClass) {
		if (destClass == Byte.class) {
			return new Byte(n.byteValue());
		}
		if (destClass == Short.class) {
			return new Short(n.shortValue());
		}
		if (destClass == Integer.class) {
			return new Integer(n.intValue());
		}
		if (destClass == Long.class) {
			return new Long(n.longValue());
		}
		if (destClass == Float.class) {
			return new Float(n.floatValue());
		}
		if (destClass == Double.class) {
			return new Double(n.doubleValue());
		}
		return n;
	}

	public static Object cast(Object obj, Class destClass) {
		if (obj == null || destClass == null) {
			return obj;
		} else if (obj.getClass() == destClass) {
			return obj;
		} else if (obj instanceof Number) {
			return cast((Number) obj, destClass);
		} else if ((obj instanceof String) && destClass == Character.class) {
			return new Character(((String) obj).charAt(0));
		} else if ((obj instanceof ArrayList) && destClass.isArray()) {
			return toArray((ArrayList) obj, destClass.getComponentType());
		} else if ((obj instanceof ArrayList) && destClass == HashMap.class) {
			return toHashMap((ArrayList) obj);
		} else {
			return obj;
		}
	}

	private static HashMap toHashMap(ArrayList a) {
		int n = a.size();
		HashMap h = new HashMap(n);

		for (int i = 0; i < n; i++) {
			h.put(new Integer(i), a.get(i));
		}
		return h;
	}

	private static Object toArray(ArrayList obj, Class componentType) {
		int n = obj.size();
		Object a = Array.newInstance(componentType, n);

		for (int i = 0; i < n; i++) {
			Array.set(a, i, cast(obj.get(i), componentType));
		}
		return a;
	}

	private static int getPos(ByteArrayInputStream stream) {
		try {
			Field pos = stream.getClass().getDeclaredField("pos");

			pos.setAccessible(true);
			return pos.getInt(stream);
		} catch (Exception e) {
			return 0;
		}
	}

	private static void setPos(ByteArrayInputStream stream, int p) {
		try {
			Field pos = stream.getClass().getDeclaredField("pos");

			pos.setAccessible(true);
			pos.setInt(stream, p);
		} catch (Exception e) {
		}
	}

	public static Object unserialize(byte[] ss) throws IllegalAccessException {
		return unserialize(ss, null, "UTF-8");
	}

	public static Object unserialize(byte[] ss, String charset)
			throws IllegalAccessException {
		return unserialize(ss, null, charset);
	}

	public static Object unserialize(byte[] ss, Class cls)
			throws IllegalAccessException {
		return unserialize(ss, cls, "UTF-8");
	}

	public static Object unserialize(byte[] ss, Class cls, String charset)
			throws IllegalAccessException {
		int hv = 1;
		ByteArrayInputStream stream = new ByteArrayInputStream(ss);
		Object result = unserialize(stream, new HashMap(), hv, new HashMap(),charset).value;

		try {
			stream.close();
		} catch (Exception e) {
		}
		return cast(result, cls);
	}

	private static UnSerializeResult unserialize(ByteArrayInputStream stream,
			HashMap ht, int hv, HashMap rt, String charset)
			throws IllegalAccessException {
		Object obj;

		switch (stream.read()) {
		case __N:
			obj = readNull(stream);
			ht.put(new Integer(hv++), obj);
			return new UnSerializeResult(obj, hv);

		case __b:
			obj = readBoolean(stream);
			ht.put(new Integer(hv++), obj);
			return new UnSerializeResult(obj, hv);

		case __i:
			obj = readInteger(stream);
			ht.put(new Integer(hv++), obj);
			return new UnSerializeResult(obj, hv);

		case __d:
			obj = readDouble(stream);
			ht.put(new Integer(hv++), obj);
			return new UnSerializeResult(obj, hv);

		case __s:
			obj = readString(stream, charset);
			ht.put(new Integer(hv++), obj);
			return new UnSerializeResult(obj, hv);

		case __U:
			obj = readUnicodeString(stream);
			ht.put(new Integer(hv++), obj);
			return new UnSerializeResult(obj, hv);

		case __r:
			return readRef(stream, ht, hv, rt);

		case __a:
			return readArray(stream, ht, hv, rt, charset);

		case __O:
			return readObject(stream, ht, hv, rt, charset);

		case __C:
			return readCustomObject(stream, ht, hv, charset);

		case __R:
			return readPointRef(stream, ht, hv, rt);

		default:
			return null;
		}
	}

	private static String readNumber(ByteArrayInputStream stream) {
		StringBuffer sb = new StringBuffer();
		int i = stream.read();

		while ((i != __Semicolon) && (i != __Colon)) {
			sb.append((char) i);
			i = stream.read();
		}
		return sb.toString();
	}

	private static Object readNull(ByteArrayInputStream stream) {
		stream.skip(1);
		return null;
	}

	private static Boolean readBoolean(ByteArrayInputStream stream) {
		stream.skip(1);
		Boolean b = new Boolean(stream.read() == __1);

		stream.skip(1);
		return b;
	}

	private static Number readInteger(ByteArrayInputStream stream) {
		stream.skip(1);
		String i = readNumber(stream);

		try {
			return new Byte(i);
		} catch (Exception e1) {
			try {
				return new Short(i);
			} catch (Exception e2) {
				return new Integer(i);
			}
		}
	}

	private static Number readDouble(ByteArrayInputStream stream) {
		stream.skip(1);
		String d = readNumber(stream);

		if (d.equals(__NAN)) {
			return new Double(Double.NaN);
		}
		if (d.equals(__INF)) {
			return new Double(Double.POSITIVE_INFINITY);
		}
		if (d.equals(__NINF)) {
			return new Double(Double.NEGATIVE_INFINITY);
		}
		try {
			return new Long(d);
		} catch (Exception e1) {
			try {
				Float f = new Float(d);

				if (f.isInfinite()) {
					return new Double(d);
				} else {
					return f;
				}
			} catch (Exception e2) {
				return new Float(0);
			}
		}
	}

	private static String readString(ByteArrayInputStream stream, String charset) {
		stream.skip(1);
		int len = Integer.parseInt(readNumber(stream));

		stream.skip(1);
		byte[] buf = new byte[len];

		stream.read(buf, 0, len);
		String s = getString(buf, charset);

		stream.skip(2);
		return s;
	}

	private static String readUnicodeString(ByteArrayInputStream stream) {
		stream.skip(1);
		int l = Integer.parseInt(readNumber(stream));

		stream.skip(1);
		StringBuffer sb = new StringBuffer(l);
		int c;

		for (int i = 0; i < l; i++) {
			if ((c = stream.read()) == __Slash) {
				char c1 = (char) stream.read();
				char c2 = (char) stream.read();
				char c3 = (char) stream.read();
				char c4 = (char) stream.read();

				sb.append((char) (Integer.parseInt(new String(new char[] { c1,
						c2, c3, c4 }), 16)));
			} else {
				sb.append((char) c);
			}
		}
		stream.skip(2);
		return sb.toString();
	}

	private static UnSerializeResult readRef(ByteArrayInputStream stream,
			HashMap ht, int hv, HashMap rt) {
		stream.skip(1);
		Integer r = new Integer(readNumber(stream));

		if (rt.containsKey(r)) {
			rt.put(r, new Boolean(true));
		}
		Object obj = ht.get(r);

		ht.put(new Integer(hv++), obj);
		return new UnSerializeResult(obj, hv);
	}

	private static UnSerializeResult readPointRef(ByteArrayInputStream stream,
			HashMap ht, int hv, HashMap rt) {
		stream.skip(1);
		Integer r = new Integer(readNumber(stream));

		if (rt.containsKey(r)) {
			rt.put(r, new Boolean(true));
		}
		Object obj = ht.get(r);

		return new UnSerializeResult(obj, hv);
	}

	private static UnSerializeResult readArray(ByteArrayInputStream stream,
			HashMap ht, int hv, HashMap rt, String charset)
			throws IllegalAccessException {
		stream.skip(1);
		int n = Integer.parseInt(readNumber(stream));

		stream.skip(1);
		HashMap h = new HashMap(n);
		ArrayList al = new ArrayList(n);
		Integer r = new Integer(hv);

		rt.put(r, new Boolean(false));
		int p = getPos(stream);

		ht.put(new Integer(hv++), h);
		for (int i = 0; i < n; i++) {
			Object key;

			switch (stream.read()) {
			case __i:
				key = cast(readInteger(stream), Integer.class);
				break;

			case __s:
				key = readString(stream, charset);
				break;

			case __U:
				key = readUnicodeString(stream);
				break;

			default:
				return null;
			}
			UnSerializeResult result = unserialize(stream, ht, hv, rt, charset);

			hv = result.hv;
			if (al != null) {
				if ((key instanceof Integer)
						&& (((Integer) key).intValue() == i)) {
					al.add(result.value);
				} else {
					al = null;
				}
			}
			h.put(key, result.value);
		}
		if (al != null) {
			ht.put(r, al);
			if (((Boolean) (rt.get(r))).booleanValue()) {
				hv = r.intValue() + 1;
				setPos(stream, p);
				for (int i = 0; i < n; i++) {
					int key;

					switch (stream.read()) {
					case __i:
						key = ((Integer) cast(readInteger(stream),
								Integer.class)).intValue();
						break;

					default:
						return null;
					}
					UnSerializeResult result = unserialize(stream, ht, hv, rt,
							charset);

					hv = result.hv;
					al.set(key, result.value);
				}
			}
		}
		rt.remove(r);
		stream.skip(1);
		return new UnSerializeResult(ht.get(r), hv);
	}

	private static UnSerializeResult readObject(ByteArrayInputStream stream,
			HashMap ht, int hv, HashMap rt, String charset)
			throws IllegalAccessException {
		stream.skip(1);
		int len = Integer.parseInt(readNumber(stream));

		stream.skip(1);
		byte[] buf = new byte[len];

		stream.read(buf, 0, len);
		String cn = getString(buf, charset);

		stream.skip(2);
		int n = Integer.parseInt(readNumber(stream));

		stream.skip(1);
		Class cls = getClass(cn);
		Object o;

		if (cls != null) {
			if ((o = newInstance(cls)) == null) {
				o = new HashMap(n);
			}
		} else {
			o = new HashMap(n);
		}
		ht.put(new Integer(hv++), o);
		for (int i = 0; i < n; i++) {
			String key;

			switch (stream.read()) {
			case __s:
				key = readString(stream, charset);
				break;

			case __U:
				key = readUnicodeString(stream);
				break;

			default:
				return null;
			}
			if (key.charAt(0) == (char) 0) {
				key = key.substring(key.indexOf("", 1) + 1);
			}
			UnSerializeResult result = unserialize(stream, ht, hv, rt, charset);

			hv = result.hv;
			if (o instanceof HashMap) {
				((HashMap) o).put(key, result.value);
			} else {
				Field f = getField(o, key);

				f.setAccessible(true);
				f.set(o, result.value);
			}
		}
		stream.skip(1);
		Method __wakeup = null;

		try {
			__wakeup = o.getClass().getMethod("__wakeup", new Class[0]);
			__wakeup.invoke(o, new Object[0]);
		} catch (Exception e) {
		}
		return new UnSerializeResult(o, hv);
	}

	private static UnSerializeResult readCustomObject(
			ByteArrayInputStream stream, HashMap ht, int hv, String charset) {
		stream.skip(1);
		int len = Integer.parseInt(readNumber(stream));

		stream.skip(1);
		byte[] buf = new byte[len];

		stream.read(buf, 0, len);
		String cn = getString(buf, charset);

		stream.skip(2);
		int n = Integer.parseInt(readNumber(stream));

		stream.skip(1);
		Class cls = getClass(cn);
		Object o;

		if (cls != null) {
			o = newInstance(cls);
		} else {
			o = null;
		}
		ht.put(new Integer(hv++), o);
		if (o == null) {
			stream.skip(n);
		} else if (o instanceof org.phprpc.util.Serializable) {
			byte[] b = new byte[n];

			stream.read(b, 0, n);
			((org.phprpc.util.Serializable) o).unserialize(b);
		} else {
			stream.skip(n);
		}
		stream.skip(1);
		return new UnSerializeResult(o, hv);
}

将项目中使用的序列化和反序列化方法抽离出来,放在一个工具类里面了:
SerializeUtil.java

import java.io.UnsupportedEncodingException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import com.thinkgem.jeesite.common.utils.PHPSerializer;

/**
 * 
 * 类描述:PHP序列化和反序列化工具
 * @author linmengmeng
 * 创建时间:2019年1月15日 下午4:06:58
 */
public class SerializeUtil {

	/**
	 * 字符串序列化
	 * @Title: serialize
	 * @Description: 字符串序列化
	 * @param cartIds
	 * @throws
	 * @return String    
	 */
	@SuppressWarnings("finally")
	public static String serialize(String[] cartIds) {
		String str = "";
		Map<String, Object> mapImage = new HashMap<String, Object>();
		Map<Integer, String> fileNameList = new HashMap<Integer, String>();
		try {
			for (int i = 0; i < cartIds.length; i++) {
				fileNameList.put(i + 1, cartIds[i]);
			}
			mapImage.put("buyer", fileNameList);
			byte[] a = PHPSerializer.serialize(mapImage);
			str = new String(a, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} finally {
			return str;
		}
	}
	
	/**
	 * 将字符串反序列
	 * @Title: unserialize
	 * @Description: 将字符串反序列
	 * @param content
	 * @return  
	 * @throws
	 * @return String    
	 */
	@SuppressWarnings({ "finally", "unchecked" })	
	public static String unserialize(String content){
		String string = null;
		if (StringUtils.isEmpty(content)) {
			return string;
		}
		try {
			HashMap<String, Map<Integer, String>> hashMap =  (HashMap<String, Map<Integer, String>>) PHPSerializer.unserialize(content.getBytes());
			Map<Integer, String> map = hashMap.get("buyer");
			Collection<String> values = map.values();
			String[] strings = values.toArray(new String[values.size()]);
			string = StringUtils.join(strings, ',');
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}finally {
			return string;
		}
	}

	public static void main(String[] args) {
		String[] cartIds = {"06008816930683722.jpg", "06008816930681525.jpg"};
		String serialize = serialize(cartIds);
		System.out.println(serialize);
		String unserialize = unserialize(serialize);
		System.out.println(unserialize);
		/*String unserialize = unserialize("N;");
		System.out.println(unserialize);*/
	}
}
/**Output:
a:1:{s:5:"buyer";a:2:{i:1;s:21:"06008816930683722.jpg";i:2;s:21:"06008816930681525.jpg";}}
06008816930681525.jpg,06008816930683722.jpg
*/

SerializeUtil 中的序列化和反序列化的方法是自定义的,如果不想这么麻烦可以直接参考这篇博客:https://www.cnblogs.com/ctaixw/p/6213910.html
工具类中的反序列化方法,就是参考这篇博客倒腾出来的。也可以直接使用上面PHPSerializer.java中的序列化和反序列化的方法:

	public static void main(String[] args) {
		String[] cartIds = {"06008816930683722.jpg", "06008816930681525.jpg"};
		byte[] serialize = PHPSerializer.serialize(cartIds);
		String serializeString = new String(serialize);
		System.out.println(serializeString);
		try {
			try {
				//Object unserialize = PHPSerializer.unserialize(serializeString.getBytes("utf-8"));
				@SuppressWarnings("unchecked")
				List<String> unserialize = (List<String>) PHPSerializer.unserialize(serializeString.getBytes("utf-8"));
				System.out.println(unserialize);
				String jsonString = JSON.toJSONString(unserialize);
				System.out.println(jsonString);
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}

输出:

a:2:{i:0;s:21:"06008816930683722.jpg";i:1;s:21:"06008816930681525.jpg";}
[06008816930683722.jpg, 06008816930681525.jpg]
["06008816930683722.jpg","06008816930681525.jpg"]

在注释掉的这句Object unserialize = PHPSerializer.unserialize(serializeString.getBytes("utf-8"));中可以直接当成Object类型进行输出,就可以看到原数据是从哪一种类型序列化而来的了。在将离职的同事序列化的数据给反序列回来的时候,这个输出点醒了我。

问题总是一个挨一个的过来了,现在有个问题就是,因为和PHP那边使用了同一个数据库,有些数据需要序列化一下存进去,然后他们那边反序列化之后拿出来用。

我们这边将参数序列化之后放进去,但是PHP那边却不能用。

刚开始我还以为是我们序列化的方式和PHP那边的反序列化方式不配套,不能序列和反序列之后使用的问题导致的。一直在纠结这个,今天一大早就在跟PHP那边验证这个序列化和反序列化的问题。

我这边找一个字符串,序列化之后,发给PHP那边,然后他们直接反序列化,刚开始都有点蒙蔽,试了好几遍才试出来,是配套的,也就是我们这边序列化之后的数据,他们那边反序列化一下,是可以拿到原数据的。

但是为什么用到项目里面就不行了呢,就很不解了。

早上测试时只是用的字符串测试的,是有来有回,正常的。然后我直接从数据库里面拿他们将数组序列化之后的数据进行反序列化,是可以出来数据的,反序列化出来是一个Map类型的,然后我又试了一次直接将控制台打印的map数据,直接塞在一个字符串里面,然后序列化,把序列化之后的数据给PHP那边发过去,然后他们那边解析不出来数据,到这里我就想着这没法用啊,类型不一致什么的。。。。,我们序列化的数据,他们解析不出来,他们序列化的数据,我这边解析报错,这还怎么玩。。。。。就这个潜意识导致我浪费了半天的时间。
下午来了之后,项目中的序列化的内容,看到我们这边是将数据放在map里面,然后对map进行序列化,然后将数据存进数据库的。我就是了一下自己随便写了一个map,序列化一下,发给PHP那边,让他们解析试试,结果不行,我就仔细对比了一下,发现他们那边存的数据,跟我们这边的原数据map里面的key的名称不一样。。。。。

到这里才算突然醒悟,参数名不一致了,即使他们那边反序列化成功了,也没法正常用的,那就按照他们那边的格式,将map里面的参数名都参照,将他们序列化的数据反序列化后的map里面的key,这样果然可行。。。。。

啰嗦了这么多,其实就是我们这边对原数据map进行序列化的时候,需要保证map里面的key和他们那边的原数据数组里的名称对应,这样才能有来有回。
贴一张图,看图会更清楚一些。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/linmengmeng_1314/article/details/86498683
今日推荐