1、待发送报文各字段的键(Key)按照字符串的字典顺序排序。如果字段为复合数据类型,按如下规则处理:如果数据类型是 List ,则对字段名按照字符串字典顺序排序
2、
从排序好的报文中依次取出各字段的值(Value),依次拼接起来;
3、计算整个拼接好的字符串的 MD5 值,转换为 16 进制的字符串,并赋值
给 sign 字段
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings("all")
public class ParameterOrdering {
public static void main(String[] args) {
// 测试数据
School s = new School();
s.setId("111122222");
s.setAddress("北京");
Section se = new Section();
se.setId("33326666");
se.setName("数学");
se.setRs(86);
List<Section> sectionList = new ArrayList<>();
sectionList.add(se);
s.setSectionList(sectionList);
// 签名
String paramOrder = generateSign(s);
}
public static String generateSign(Object data){
Field[] fields = data.getClass().getDeclaredFields();
List<Field> allFields = new ArrayList<>();
Class supperclass = data.getClass().getSuperclass();
while(supperclass != null){
allFields.addAll(Arrays.asList(supperclass.getDeclaredFields()));
supperclass =supperclass.getSuperclass();
}
allFields.addAll(Arrays.asList(fields));
allFields.sort(new FieldComparator());
StringBuilder stringBuilder =new StringBuilder();
try{
for(Field field:allFields){
stringBuilder.append(getValue(field,data));
}
}catch(Exception e){
e.printStackTrace();
throw new RuntimeException(e);
}
System.out.println("Json 报文中各字段排序后取得的值拼接:"+stringBuilder.toString());
return Digestutils.md5Hex(stringBuilder.toString());
}
public static String getValue(Field field, Object o) throws Exception {
field.setAccessible(true);
if (o == null || field.get(o) == null) {
return "";
}
Object value = field.get(o);
if (value.getClass().getName().startsWith("java.lang")) {
return String.valueOf(field.get(o));
} else if (value instanceof List) {
List list = (List) value;
StringBuilder stringBuilder = new StringBuilder();
for (Object object : list) {
if (object.getClass().getName().startsWith("java.lang")) {
stringBuilder.append(object);
} else {
Field[] fields = object.getClass().getDeclaredFields();
List<Field> fieldList = Arrays.asList(fields);
fieldList.sort(new FieldComparator());
for (Field f : fieldList) {
stringBuilder.append(getValue(f, object));
}
}
}
return stringBuilder.toString();
} else {
Field[] fields = field.get(o).getClass().getDeclaredFields();
List<Field> allFields = Arrays.asList(fields);
allFields.sort(new FieldComparator());
StringBuilder stringBuilder = new StringBuilder();
for (Field f : allFields) {
f.setAccessible(true);
if (f.get(field.get(o)) != null) {
stringBuilder.append(getValue(f, field.get(o)));
}
}
return stringBuilder.toString();
}
}
private static class FieldComparator implements Comparator<Field> {
public int compare(Field a, Field b) {
return a.getName().compareTo(b.getName());
}
}
}
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.binary.StringUtils;
public class Digestutils {
private static final int STREAM_BUFFER_LENGTH = 1024;
private final MessageDigest messageDigest;
public static byte[] digest(MessageDigest messageDigest, byte[] data) {
return messageDigest.digest(data);
}
public static byte[] digest(MessageDigest messageDigest, ByteBuffer data) {
messageDigest.update(data);
return messageDigest.digest();
}
public static byte[] digest(MessageDigest messageDigest, File data) throws IOException {
return updateDigest(messageDigest, data).digest();
}
public static byte[] digest(MessageDigest messageDigest, InputStream data) throws IOException {
return updateDigest(messageDigest, data).digest();
}
public static MessageDigest getDigest(String algorithm) {
try {
return MessageDigest.getInstance(algorithm);
} catch (NoSuchAlgorithmException var2) {
throw new IllegalArgumentException(var2);
}
}
public static MessageDigest getDigest(String algorithm, MessageDigest defaultMessageDigest) {
try {
return MessageDigest.getInstance(algorithm);
} catch (Exception var3) {
return defaultMessageDigest;
}
}
public static MessageDigest getMd2Digest() {
return getDigest("MD2");
}
public static MessageDigest getMd5Digest() {
return getDigest("MD5");
}
public static MessageDigest getSha1Digest() {
return getDigest("SHA-1");
}
public static MessageDigest getSha256Digest() {
return getDigest("SHA-256");
}
public static MessageDigest getSha384Digest() {
return getDigest("SHA-384");
}
public static MessageDigest getSha512Digest() {
return getDigest("SHA-512");
}
/** @deprecated */
@Deprecated
public static MessageDigest getShaDigest() {
return getSha1Digest();
}
public static byte[] md2(byte[] data) {
return getMd2Digest().digest(data);
}
public static byte[] md2(InputStream data) throws IOException {
return digest(getMd2Digest(), data);
}
public static byte[] md2(String data) {
return md2(StringUtils.getBytesUtf8(data));
}
public static String md2Hex(byte[] data) {
return Hex.encodeHexString(md2(data));
}
public static String md2Hex(InputStream data) throws IOException {
return Hex.encodeHexString(md2(data));
}
public static String md2Hex(String data) {
return Hex.encodeHexString(md2(data));
}
public static byte[] md5(byte[] data) {
return getMd5Digest().digest(data);
}
public static byte[] md5(InputStream data) throws IOException {
return digest(getMd5Digest(), data);
}
public static byte[] md5(String data) {
return md5(StringUtils.getBytesUtf8(data));
}
public static String md5Hex(byte[] data) {
return Hex.encodeHexString(md5(data));
}
public static String md5Hex(InputStream data) throws IOException {
return Hex.encodeHexString(md5(data));
}
public static String md5Hex(String data) {
return Hex.encodeHexString(md5(data));
}
/** @deprecated */
@Deprecated
public static byte[] sha(byte[] data) {
return sha1(data);
}
/** @deprecated */
@Deprecated
public static byte[] sha(InputStream data) throws IOException {
return sha1(data);
}
/** @deprecated */
@Deprecated
public static byte[] sha(String data) {
return sha1(data);
}
public static byte[] sha1(byte[] data) {
return getSha1Digest().digest(data);
}
public static byte[] sha1(InputStream data) throws IOException {
return digest(getSha1Digest(), data);
}
public static byte[] sha1(String data) {
return sha1(StringUtils.getBytesUtf8(data));
}
public static String sha1Hex(byte[] data) {
return Hex.encodeHexString(sha1(data));
}
public static String sha1Hex(InputStream data) throws IOException {
return Hex.encodeHexString(sha1(data));
}
public static String sha1Hex(String data) {
return Hex.encodeHexString(sha1(data));
}
public static byte[] sha256(byte[] data) {
return getSha256Digest().digest(data);
}
public static byte[] sha256(InputStream data) throws IOException {
return digest(getSha256Digest(), data);
}
public static byte[] sha256(String data) {
return sha256(StringUtils.getBytesUtf8(data));
}
public static String sha256Hex(byte[] data) {
return Hex.encodeHexString(sha256(data));
}
public static String sha256Hex(InputStream data) throws IOException {
return Hex.encodeHexString(sha256(data));
}
public static String sha256Hex(String data) {
return Hex.encodeHexString(sha256(data));
}
public static byte[] sha384(byte[] data) {
return getSha384Digest().digest(data);
}
public static byte[] sha384(InputStream data) throws IOException {
return digest(getSha384Digest(), data);
}
public static byte[] sha384(String data) {
return sha384(StringUtils.getBytesUtf8(data));
}
public static String sha384Hex(byte[] data) {
return Hex.encodeHexString(sha384(data));
}
public static String sha384Hex(InputStream data) throws IOException {
return Hex.encodeHexString(sha384(data));
}
public static String sha384Hex(String data) {
return Hex.encodeHexString(sha384(data));
}
public static byte[] sha512(byte[] data) {
return getSha512Digest().digest(data);
}
public static byte[] sha512(InputStream data) throws IOException {
return digest(getSha512Digest(), data);
}
public static byte[] sha512(String data) {
return sha512(StringUtils.getBytesUtf8(data));
}
public static String sha512Hex(byte[] data) {
return Hex.encodeHexString(sha512(data));
}
public static String sha512Hex(InputStream data) throws IOException {
return Hex.encodeHexString(sha512(data));
}
public static String sha512Hex(String data) {
return Hex.encodeHexString(sha512(data));
}
/** @deprecated */
@Deprecated
public static String shaHex(byte[] data) {
return sha1Hex(data);
}
/** @deprecated */
@Deprecated
public static String shaHex(InputStream data) throws IOException {
return sha1Hex(data);
}
/** @deprecated */
@Deprecated
public static String shaHex(String data) {
return sha1Hex(data);
}
public static MessageDigest updateDigest(MessageDigest messageDigest, byte[] valueToDigest) {
messageDigest.update(valueToDigest);
return messageDigest;
}
public static MessageDigest updateDigest(MessageDigest messageDigest, ByteBuffer valueToDigest) {
messageDigest.update(valueToDigest);
return messageDigest;
}
public static MessageDigest updateDigest(MessageDigest digest, File data) throws IOException {
BufferedInputStream stream = new BufferedInputStream(new FileInputStream(data));
MessageDigest var3;
try {
var3 = updateDigest(digest, (InputStream) stream);
} finally {
stream.close();
}
return var3;
}
public static MessageDigest updateDigest(MessageDigest digest, InputStream data) throws IOException {
byte[] buffer = new byte[1024];
for (int read = data.read(buffer, 0, 1024); read > -1; read = data.read(buffer, 0, 1024)) {
digest.update(buffer, 0, read);
}
return digest;
}
public static MessageDigest updateDigest(MessageDigest messageDigest, String valueToDigest) {
messageDigest.update(StringUtils.getBytesUtf8(valueToDigest));
return messageDigest;
}
public static boolean isAvailable(String messageDigestAlgorithm) {
return getDigest(messageDigestAlgorithm, (MessageDigest) null) != null;
}
/** @deprecated */
@Deprecated
public Digestutils() {
this.messageDigest = null;
}
public Digestutils(MessageDigest digest) {
this.messageDigest = digest;
}
public Digestutils(String name) {
this(getDigest(name));
}
public MessageDigest getMessageDigest() {
return this.messageDigest;
}
public byte[] digest(byte[] data) {
return updateDigest(this.messageDigest, data).digest();
}
public byte[] digest(String data) {
return updateDigest(this.messageDigest, data).digest();
}
public byte[] digest(ByteBuffer data) {
return updateDigest(this.messageDigest, data).digest();
}
public byte[] digest(File data) throws IOException {
return updateDigest(this.messageDigest, data).digest();
}
public byte[] digest(InputStream data) throws IOException {
return updateDigest(this.messageDigest, data).digest();
}
public String digestAsHex(byte[] data) {
return Hex.encodeHexString(this.digest(data));
}
public String digestAsHex(String data) {
return Hex.encodeHexString(this.digest(data));
}
public String digestAsHex(ByteBuffer data) {
return Hex.encodeHexString(this.digest(data));
}
public String digestAsHex(File data) throws IOException {
return Hex.encodeHexString(this.digest(data));
}
public String digestAsHex(InputStream data) throws IOException {
return Hex.encodeHexString(this.digest(data));
}
}
方法generateSign中Object data为实体类
import java.util.List;
public class School {
public String id;
public String address;
public List<Section> sectionList;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public List<Section> getSectionList() {
return sectionList;
}
public void setSectionList(List<Section> sectionList) {
this.sectionList = sectionList;
}
}
public class Section {
public String id;
public String name;
public int rs;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getRs() {
return rs;
}
public void setRs(int rs) {
this.rs = rs;
}
}