mock 数据随机生成工具(支持任意对象)

在写接口文档的时候会有这样的需求,写给前端的接口文档,前端会问你要一份 mock 数据 , 但是在写接口文档的时候接口还没有实现,只定义了输入和输出。这个时候就非常需要一种能创建模拟数据的工具,但找遍全网好像都没有这样的工具,所以我决定自己来写一个。

这个工具的目标很明确 :输入 Class ,输出 Object ;

找到了类似的工具 : jmockdata , jpopulator 但是这两个都和业务数据无关 , 只能生成随机数据

这个很容易想到是用反射来实现, 但是在使用反射的过程中遇到了一些问题,并完善了我使用反射的一些知识点,特此记录一下。

  1. 之前一直以为 Class 就是顶层类型,是所有类型的模板,直到碰到这个问题,当类中有 List<对象> ,Map<String,对象> 时,我如果不知道 “对象” 是什么类型,我就无法为其生成随机数据 ; 其实 Type 才是 Java 中的顶层类型 ,Class 只是 Type 的一个实现,也是最重要的实现 ,其它实现有 ParameterizedType ,GenericArrayType , TypeVariable, WildcardType 都是针对于泛型的,List<对象> 的 Type 实现就是 ParameterizedType
  2. 数组整个其实就是一个对象,它的构建实例和设置值获取值都是使用 Array 中的方法,我开始以为所有的数组可以使用 Object [] 放进去,但一直是报 type argument miss match
    • 构建数组对象,count 个数据 Array.newInstance(componentType, count)
    • 给数组对象设置值 Array.set(arr,i,value)
    • 获取数组的某个位置的值 Array.get(arr,i)
  3. 为了可以将我的这个工具部署到网络上去,供所有人使用,我工程本地肯定是没有别人的类的,所以我选择让使用者上传他们的 dto 的包到我的项目,然后为其创建一个类加载器,然后在反射的时候使用这个具体的类加载器,就可以生成随机数据了。
  4. 不足之处,本文工具对数组的支持只能支持一维数组 ,泛型对象支持 List,Map,Set , 只支持一级泛型,像 List<String[]> ,List<Map<XX,XX>> 没有做支持处理

下面是核心代码

这份代码可能不是很全,因为我的一些随机的数据源没有放上来,此处只是核心代码,使用者可以访问我的 git 仓库 拿到那些数据源来实现自己的随机数据生成; 如果你觉得麻烦,也可以直接下载我的工具 sanri-tools-maven 直接拿来用。

需要引入的包

spring-core,commons-lang3,fastjson,commons-io,lombok,slf4j,logback

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.22</version>
</dependency>

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.8.1</version>
</dependency>
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>

<!-- log -->
 <dependency>
     <groupId>ch.qos.logback</groupId>
     <artifactId>logback-classic</artifactId>
     <version>1.2.3</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.30</version>
</dependency>

<!-- spring-core 主要使用其反射的功能  -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.3.6.RELEASE</version>
</dependency>

这个是不使用类加载器的版本

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.cglib.core.ReflectUtils;
import org.springframework.util.ReflectionUtils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * 随机数据生成
 */
@Slf4j
public class RandomDataService {

    /**
     * 给一个类型注入数据; 总方法,调用这个来生成随机数据
     * @param clazz
     * @return
     */
    public Object populateData(Class<?> clazz){
        if(isPrimitiveExtend(clazz)){
            return populateDataOrigin(null,clazz);
        }
        return populateDataComplex(clazz);
    }

    /**
     * 这个方法可以注入简单类型和复杂类型,注入单个类型
     * @param type
     * @param columnName
     * @return
     */
    private Object populateData(Type type,String columnName){
        if(type instanceof Class){
            Class propertyType = (Class) type;
            if(propertyType == Object.class){
                // 总对象不处理,因为不知道要注入什么值
                log.info("对象中含有 object 对象,不作处理");
                return null;
            }
            if (isPrimitiveExtend(propertyType)){
                return populateDataOrigin(columnName,propertyType);
            }
            return populateDataComplex(propertyType);
        }
        // 接下来这些都是 ParameterizedType
        if(type instanceof ParameterizedType){
            ParameterizedType parameterizedType = (ParameterizedType) type;
            // rawType 认为一定是 class ,其实还是有风险的,先这样吧
            Class propertyType = (Class) parameterizedType.getRawType();
            if(propertyType == List.class || propertyType == Set.class){
                return populateCollectionData(parameterizedType, columnName);
            }
            if(propertyType == Map.class){
               return populateMapData(parameterizedType, columnName);
            }
        }

        log.error("不支持的类型:[{}]",type);
        return null;
    }

    /**
     * 注入 map 数据
     * @param writeMethod
     * @param columnName
     * @return
     */
    private Map populateMapData(ParameterizedType parameterType, String columnName){
        Map map = new HashMap();

        Class keyTypeArgument = (Class) parameterType.getActualTypeArguments()[0];
        Class valueTypeArgument = (Class) parameterType.getActualTypeArguments()[1];

        // 随机创建 2~ 10 个键值对
        int count = RandomUtils.nextInt(2, 10);

        for (int i = 0; i < count; i++) {
            Object key = populateData(keyTypeArgument, columnName);
            Object value = populateData(valueTypeArgument, columnName);
            map.put(key,value);
        }
        return map;
    }

    /**
     * 注入复杂对象值,只能注入复杂类型 ; 这个是真正的主入口,注入一个复杂类型对象数据
     * @param clazz
     * @return
     */
    private Object populateDataComplex(Class<?> clazz) {
        Object object = ReflectUtils.newInstance(clazz);

        PropertyDescriptor[] beanSetters = ReflectUtils.getBeanSetters(clazz);
        for (PropertyDescriptor beanSetter : beanSetters) {
            Method writeMethod = beanSetter.getWriteMethod();
            String columnName = beanSetter.getName();
            Type genericParameterType = writeMethod.getGenericParameterTypes()[0];
            Object populateData = populateData(genericParameterType, columnName);

            ReflectionUtils.invokeMethod(writeMethod, object, populateData);
        }
        return object;
    }

    /**
     * 对于 set , list  等 注入数据
     * @param writeMethod
     * @param list
     * @param columnName
     * @return
     */
    private Collection populateCollectionData(ParameterizedType genericParameterType, String columnName) {
        Collection collection = null;
        Class rawType = (Class) genericParameterType.getRawType();
        if(rawType == List.class){
            collection = new ArrayList();
        }else if(rawType == Set.class){
            collection = new HashSet();
        }

        Class typeArgument = (Class) genericParameterType.getActualTypeArguments()[0];
        // 每个 List 创建 随机 2 ~ 10 条数据
        int count = RandomUtils.nextInt(2, 10);
        for (int i = 0; i < count; i++) {
            Object populateData = populateData(typeArgument, columnName);
            collection.add(populateData);
        }

        return collection;
    }

    /**
     * 对某一列注入原始类型的数据
     * @param columnName
     * @param propertyType
     * @return
     */
    private Object populateDataOrigin( String columnName, Class<?> propertyType) {
        columnName = Objects.toString(columnName,"");

        if(propertyType == String.class){
            int randomLength = RandomUtils.nextInt(5,20);
            String value = RandomStringUtils.randomAlphabetic(randomLength);
            String lowerCase = columnName.toLowerCase();
            if(lowerCase.contains("ip")){
                value = "114.114.114.114";
            }else
            if(lowerCase.contains("idcard")){
                value = RandomUtil.idcard();
            }else
            if(lowerCase.contains("mail")){
                value = RandomUtil.email(30);
            }else
            if(lowerCase.contains("phone") ){
                value = RandomUtil.phone();
            }else
            if(lowerCase.contains("name") || lowerCase.contains("user")){
                value = RandomUtil.username();
            }else
            if(lowerCase.contains("address")){
                value = RandomUtil.address();
            }else
            if(lowerCase.contains("uuid")){
                value = UUID.randomUUID().toString().replace("-","");
            }else
            if(lowerCase.contains("job")){
                value = RandomUtil.job();
            }else
            if(lowerCase.contains("status") || lowerCase.contains("state")){
                value = RandomUtil.status("1","2","3");
            }else
            if(lowerCase.contains("time") || (lowerCase.contains("date") && !lowerCase.equals("update")) || lowerCase.contains("birthday")){
                // 这里可以做时间格式转换,获取字段上的配置
                value =  DateFormatUtils.ISO_DATETIME_FORMAT.format(RandomUtil.date());
            } else
            if(lowerCase.contains("lat")){
                String randomLongLat = RandomUtil.randomLongLat(25, 115, 26, 160);
                value = StringUtils.split(randomLongLat,",")[1];
            }else
            if(lowerCase.contains("lon") || lowerCase.contains("lang")){
                String randomLongLat = RandomUtil.randomLongLat(25, 115, 26, 160);
                value = StringUtils.split(randomLongLat,",")[0];
            }else if(lowerCase.contains("pic") || lowerCase.contains("photo")){
                value = RandomUtil.photoURL();
            }else if(lowerCase.contains("num")){
                value = RandomUtils.nextInt(10,1000) + "";
            }else if(lowerCase.contains("url")){
                value = RandomUtil.url();
            }
            else if(lowerCase.contains("no") || lowerCase.contains("code")){
                value = RandomStringUtils.randomNumeric(4);
            }

            return value;
        }
        if(propertyType == Date.class){
            return RandomUtil.date();
        }
        if(propertyType == BigDecimal.class){
            BigDecimal bigDecimal = new BigDecimal(RandomUtils.nextDouble(100,2000000));
            bigDecimal = bigDecimal.setScale(2, RoundingMode.HALF_UP);
            return bigDecimal;
        }
        if (propertyType == Integer.class || propertyType == int.class){
            Integer num = RandomUtils.nextInt(10,1000);
            if(columnName.toLowerCase().contains("age")) {
                num = RandomUtils.nextInt(20,150);
            }
            return num;
        }
        if(propertyType == Long.class ||  propertyType == long.class){
            return RandomUtils.nextLong(10,10000000);
        }
        if(propertyType == Float.class || propertyType == float.class){
            return RandomUtils.nextFloat(10,1000);
        }
        if(propertyType == Double.class || propertyType == double.class){
            return RandomUtils.nextDouble(10,1000);
        }
        if(propertyType == Boolean.class || propertyType == boolean.class){
            return RandomUtils.nextBoolean();
        }
        if(propertyType == Short.class || propertyType == short.class){
            int nexInt = RandomUtils.nextInt(129, 500);
            return new Integer(nexInt).shortValue();
        }
        if(propertyType == Character.class || propertyType == char.class){
            return RandomStringUtils.randomAlphanumeric(1).charAt(0);
        }
        if(propertyType == Byte.class || propertyType == byte.class){
            return RandomUtils.nextBytes(1)[0];
        }

        // 数组只能支持一维数组,不要使用二维数组
        if(propertyType.isArray()){
            Class<?> componentType = propertyType.getComponentType();
            int count = RandomUtils.nextInt(2, 10);
            Object arr = Array.newInstance(componentType, count);

            for (int i = 0; i < count; i++) {
                Object value = populateData(componentType);
                Array.set(arr,i,value);
            }
            return arr;
        }

        log.error("无法处理的类型[{}]",propertyType);
        return null;
    }


    /**
     * 判断是否是原始型扩展
     * 包含 原始型及包装类,String,Date,BigDecimal,Array 数组也当原始型处理,因为数组类型必须要匹配,不能自动拆箱装箱
     * @param propertyType
     * @return
     */
    private boolean isPrimitiveExtend(Class<?> propertyType) {
        return ClassUtils.isPrimitiveOrWrapper(propertyType) || propertyType == String.class || propertyType == Date.class || propertyType == BigDecimal.class || propertyType.isArray();
    }
}

RandomUtil

package sanri.utils;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;

import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URI;
import java.nio.charset.Charset;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 
 * 创建时间:2016-9-24下午5:33:29<br/>
 * 创建者:sanri<br/>
 * 功能:扩展自 org.apache.commons.lang,加入一些源数据 <br/>
 */
public class RandomUtil extends RandomStringUtils {
	public static final String FIRST_NAME="赵钱孙李周吴郑王冯陈褚卫蒋沈韩杨朱秦尤许何吕施张孔曹严华金魏陶姜戚谢邹喻柏水窦章云苏潘葛奚范彭郎鲁韦昌马苗凤花方俞任袁柳酆鲍史唐费廉岑薛雷贺倪汤滕殷罗毕郝邬安常乐于时傅皮卞齐康伍余元卜顾孟平黄和穆萧尹姚邵湛汪祁毛禹狄米贝明臧计伏成戴谈宋茅庞熊纪舒屈项祝董梁杜阮蓝闵席季麻强贾路娄危江童颜郭梅盛林刁钟徐邱骆高夏蔡田樊胡凌霍虞万支柯昝管卢莫经房裘缪干解应宗丁宣贲邓郁单杭洪包诸左石崔吉钮龚程嵇邢滑裴陆荣翁荀羊於惠甄麴家封芮羿储靳汲邴糜松井段富巫乌焦巴弓牧隗山谷车侯宓蓬全郗班仰秋仲伊宫宁仇栾暴甘钭厉戎祖武符刘景詹束龙叶幸司韶郜黎蓟薄印宿白怀蒲邰从鄂索咸籍赖卓蔺屠蒙池乔阴郁胥能苍双闻莘党翟谭贡劳逄姬申扶堵冉宰郦雍舄璩桑桂濮牛寿通边扈燕冀郏浦尚农温别庄晏柴瞿阎充慕连茹习宦艾鱼容向古易慎戈廖庾终暨居衡步都耿满弘匡国文寇广禄阙东殴殳沃利蔚越夔隆师巩厍聂晁勾敖融冷訾辛阚那简饶空曾毋沙乜养鞠须丰巢关蒯相查後荆红游竺权逯盖益桓公晋楚闫法汝鄢涂钦仉督岳帅缑亢况后有琴商牟佘佴伯赏墨哈谯笪年爱阳佟";
	public static final String GIRL="秀娟英华慧巧美娜静淑惠珠翠雅芝玉萍红娥玲芬芳燕彩春菊兰凤洁梅琳素云莲真环雪荣爱妹霞香月莺媛艳瑞凡佳嘉琼勤珍贞莉桂娣叶璧璐娅琦晶妍茜秋珊莎锦黛青倩婷姣婉娴瑾颖露瑶怡婵雁蓓纨仪荷丹蓉眉君琴蕊薇菁梦岚苑婕馨瑗琰韵融园艺咏卿聪澜纯毓悦昭冰爽琬茗羽希宁欣飘育滢馥筠柔竹霭凝晓欢霄枫芸菲寒伊亚宜可姬舒影荔枝思丽";  
    public static final String BOY="伟刚勇毅俊峰强军平保东文辉力明永健鸿世广万志义兴良海山仁波宁贵福生龙元全国胜学祥才发武新利清飞彬富顺信子杰涛昌成康星光天达安岩中茂进林有坚和彪博诚先敬震振壮会思群豪心邦承乐绍功松善厚庆磊民友裕河哲江超浩亮政谦亨奇固之轮翰朗伯宏言若鸣朋斌梁栋维启克伦翔旭鹏泽晨辰士以建家致树炎德行时泰盛雄琛钧冠策腾楠榕风航弘正日";

	public static JSONObject AREANO_MAP;
	public static JSONObject CITY_LIST;
    public static final String[] EMAIL_SUFFIX="@gmail.com,@yahoo.com,@msn.com,@hotmail.com,@aol.com,@ask.com,@live.com,@qq.com,@0355.net,@163.com,@163.net,@263.net,@3721.net,@yeah.net,@googlemail.com,@126.com,@sina.com,@sohu.com,@yahoo.com.cn".split(",");
    public static final String[] PHONE_SEGMENT = "133,149,153,173,177,180,181,189,199,130,131,132,145,155,156,166,171,175,176,185,186,166,135,136,137,138,139,147,150,151,152,157,158,159,172,178,182,183,184,187,188,198,170".split(",");
    public static String [] ADDRESS_LIST;
    public static String [] JOBS;
	static{
		InputStreamReader reader = null;
		Charset charset = Charset.forName("utf-8");
		try {
			URI resource = RandomUtil.class.getResource(".").toURI();
			URI addressURI = resource.resolve(new URI("data/address.string"));
			URI citylistURI = resource.resolve(new URI("data/city.min.json"));
			URI idcodeURI = resource.resolve(new URI("data/idcodearea.json"));
			URI jobURI = resource.resolve(new URI("data/job.string"));

			ADDRESS_LIST = StringUtils.split(IOUtils.toString(addressURI,charset),',');
			CITY_LIST = JSONObject.parseObject(IOUtils.toString(citylistURI,charset));
			AREANO_MAP = JSONObject.parseObject(IOUtils.toString(idcodeURI,charset));
			JOBS = StringUtils.split(IOUtils.toString(jobURI,charset),',');
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			IOUtils.closeQuietly(reader);
		}
	}

	/**
	 * 功能:生成 length 个中文 <br/>
	 * 创建时间:2016-4-16上午11:24:40 
	 * 作者:sanri 
	 * */
	public static String chinese(int length, String src) {
		String ret = "";
		if(!StringUtils.isBlank(src)){
			return random(length, src.toCharArray());
		}
		for (int i = 0; i < length; i++) {
			String str = null;
			int hightPos, lowPos; // 定义高低位
			Random random = new Random();
			hightPos = (176 + Math.abs(random.nextInt(39))); // 获取高位值
			lowPos = (161 + Math.abs(random.nextInt(93))); // 获取低位值
			byte[] b = new byte[2];
			b[0] = (new Integer(hightPos).byteValue());
			b[1] = (new Integer(lowPos).byteValue());
			try {
				str = new String(b, "GBk"); // 转成中文
			} catch (UnsupportedEncodingException ex) {
				ex.printStackTrace();
			}
			ret += str;
		}
		return ret;
	}
	
	/**
	 * 
	 * 功能:随机生成用户名<br/>
	 * 创建时间:2017-8-13上午8:04:32<br/>
	 * 作者:sanri<br/>
	 * @return<br/>
	 */
	public static String username(){
		boolean sex = (randomNumber(100) % 2 == 0 );
		int secondNameLength = (int) randomNumber(2);
		String firstName = random(1, FIRST_NAME);
		String srcChars = sex ? BOY : GIRL;
		String secondName = random(secondNameLength,srcChars );
		return firstName+secondName;
	}
	/**
	 *
	 * 功能:给定格式 ,开始时间,结束时间,生成一个在开始和结束内的日期<br/>
	 * 创建时间:2016-4-16下午3:57:38<br/>
	 * 作者:sanri<br/>
	 * 入参说明:<br/>
	 * 出参说明:字符串日期类型由 format 格式化<br/>
	 * @throws ParseException<br/>
	 */
	public static String date(String format,String begin,String end) throws ParseException{
		if(StringUtils.isBlank(format)){
			format = "yyyyMMdd";
		}
		long timstamp = timstamp(format, begin, end);
		return DateFormatUtils.format(timstamp, format);
	}
	/**
	 *
	 * 功能:得到由开始时间和结束时间内的一个时间戳<br/>
	 * 创建时间:2016-4-16下午4:07:31<br/>
	 * 作者:sanri<br/>
	 * 入参说明:<br/>
	 * 出参说明:如果时间给的不对,则是当前时间<br/>
	 * @param format
	 * @param begin
	 * @param end
	 * @return
	 * @throws ParseException<br/>
	 */
	public static long timstamp(String format,String begin,String end) throws ParseException{
		if(StringUtils.isBlank(format)){
			format = "yyyyMMdd";
		}
		Date now = new Date();
		if(StringUtils.isBlank(begin)){
			begin = DateFormatUtils.format(now,format);
		}
		if(StringUtils.isBlank(end)){
			end = DateFormatUtils.format(now,format);
		}
		String [] formats = new String []{format};
		long beginDateTime = DateUtils.parseDate(begin, formats).getTime();
		long endDateTime = DateUtils.parseDate(end, formats).getTime();
		if(beginDateTime > endDateTime){
			return now.getTime();
		}
		long random = randomNumber(endDateTime - beginDateTime);
		return random + beginDateTime;
	}
	/**
	 *
	 * 功能:生成限制数字内的数字 0 ~ limit 包括 limit<br/>
	 * 创建时间:2016-9-24下午6:07:05<br/>
	 * 作者:sanri<br/>
	 * 使用 RandomUtils.nextInt() 替代
	 */
	@Deprecated
	public static long randomNumber(long limit) {
		return Math.round(Math.random() * limit);
	}
	/**
	 *
	 * 功能:生成身份证号<br/>
	 * 创建时间:2016-4-16下午2:31:37<br/>
	 * 作者:sanri<br/>
	 * 入参说明:[area:区域号][yyyyMMdd:出生日期][sex:偶=女,奇=男]<br/>
	 * 出参说明:330602 19770717 201 1<br/>
	 *
	 * @param area
	 * @param yyyyMMdd
	 * @param sno
	 * @return<br/>
	 */
	public static String idcard(String area, String yyyyMMdd, String sno) {
		String idCard17 = area + yyyyMMdd + sno;
		int[] validas = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
		char[] idCards = idCard17.toCharArray();
		int count = 0;
		for (int i = 0; i < validas.length; i++) {
			count += Integer.valueOf(String.valueOf(idCards[i])) * validas[i];
		}
		String lastNum = String.valueOf((12 - count % 11) % 11);
		lastNum = "10".equals(lastNum) ? "x":lastNum;
		return idCard17 + lastNum;
	}
	public static String idcard(String area){
		String format = "yyyyMMdd";
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		try {
			String yyyyMMdd = date(format, "19990101", sdf.format(new Date()));
			String sno = randomNumeric(3);
			return idcard(area, yyyyMMdd, sno);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return "";
	}

    /**
     * 随机生成身份证号
	 * 暂时有问题 TODO 先使用临时方案
	 * @return
     */
	public static String idcard(){
		Set<String> areaNos = AREANO_MAP.keySet();
		List<String> areaList = new ArrayList<String>();
		areaList.addAll(areaNos);
		String area = areaList.get((int)randomNumber(areaList.size() - 1));
		while (area.length() != 6){
			area = areaList.get((int)randomNumber(areaList.size() - 1));
		}
		return idcard(area);
	}
	/**
	 *
	 * 功能:随机生成地址<br/>
	 * 创建时间:2016-4-16下午6:19:14<br/>
	 * 作者:sanri<br/>
	 * 入参说明:<br/>
	 * 出参说明:<br/>
	 * @return<br/>
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static String address(){
		List<Map> cityList = (List<Map>) CITY_LIST.get("citylist");
		Map provinceEntry = cityList.get((int)randomNumber(cityList.size() - 1));
		String province = String.valueOf(provinceEntry.get("p"));
		List<Map> city = (List<Map>) provinceEntry.get("c");
		Map areaEntry = city.get((int)randomNumber(city.size() - 1));
		String area = String.valueOf(areaEntry.get("n"));
		List<Map> area2 = (List<Map>) areaEntry.get("a");
		String s = "";
		if(area2 != null){
			Map cityEntry = area2.get((int)randomNumber(area2.size() - 1));
			s = String.valueOf(cityEntry.get("s"));
		}
		return province + area + s + ADDRESS_LIST[(int)randomNumber(ADDRESS_LIST.length - 1)];
	}
	/**
	 *
	 * 功能:随机邮件地址,length 指 用户名长度<br/>
	 * 创建时间:2016-9-24下午6:11:54<br/>
	 * 作者:sanri<br/>
	 */
	public static String email(int length){
		return randomAlphanumeric(length)+EMAIL_SUFFIX[(int)randomNumber(EMAIL_SUFFIX.length - 1)];
	}

	/**
	 * 随机职业
	 * @return
	 */
	public static String job(){
		return JOBS[(int)randomNumber(JOBS.length - 1)];
	}
	/**
	 * 生成手机号
	 * @param segment
	 * @return
	 */
	public static String phone(String segment){
		if(StringUtils.isBlank(segment)){
			return phone();
		}
		int length = segment.length();
		int randomLength = 11 - length;
		String randomNumeric = randomNumeric(randomLength);
		return segment+randomNumeric;
	}

	/**
	 * 随机前缀手机号
	 * @return
	 */
	public static String phone(){
		String segment = PHONE_SEGMENT[(int)randomNumber(PHONE_SEGMENT.length - 1)];
		return phone(segment);
	}

	/**
	 * 生成一个随机日期
	 * @param begin
	 * @param end
	 * @return
	 */
	public static Date date(Date begin ,Date end){
		if(begin == null || end == null || end.before(begin)){
			throw new IllegalArgumentException("请传入正确数据");
		}
		long minus = end.getTime() - begin.getTime();
		long computedMinus = RandomUtils.nextLong(0, minus);
		long computedDateTime = begin.getTime() + computedMinus;
		return new Date(computedDateTime);
	}

	/**
	 * 随机日期
	 * @return
	 */
	public static Date date(){
		return date(new Date(0L),new Date());
	}

	/**
	 * 随机状态量
	 * @param statuses
	 * @return
	 */
	public static int status(int... statuses){
		int index = RandomUtils.nextInt(0, statuses.length);
		return statuses[index];
	}
	public static String status(String...statuses){
		int index = RandomUtils.nextInt(0, statuses.length);
		return statuses[index];
	}

	/**
	 * @Description: 在矩形内随机生成经纬度
	 * @param minLong:最小经度
	 * @param maxLong: 最大经度
	 * @param minLat:最小纬度
	 * @param maxLat:最大纬度
	 */
	public static String randomLongLat(double minLong, double maxLong, double minLat, double maxLat) {
		BigDecimal decimal = new BigDecimal(Math.random() * (maxLong - minLong) + minLong);
		String lon = decimal.setScale(6, BigDecimal.ROUND_HALF_UP).toString();// 小数后6位
		decimal = new BigDecimal(Math.random() * (maxLat - minLat) + minLat);
		String lat = decimal.setScale(6, BigDecimal.ROUND_HALF_UP).toString();
		return lon+","+lat;
	}

	/**
	 * 随机几个图片 url
	 * @param count
	 * @return
	 */
	public static String photoURL() {
		// 这个是已经找好的图片地址
		String [] urls = {
				"http://img1.imgtn.bdimg.com/it/u=2346282507,2171850944&fm=26&gp=0.jpg",
				"http://img5.imgtn.bdimg.com/it/u=2945908607,1627227886&fm=26&gp=0.jpg",
				"http://attach.bbs.miui.com/forum/201310/19/235356fyjkkugokokczyo0.jpg",
				"http://attachments.gfan.net.cn/forum/201504/14/075409wgwijxiax3i4wihw.jpg",
				"http://attach.bbs.miui.com/forum/201401/11/145825zn1sxa8anrg11gt1.jpg"
		};
		int index = RandomUtils.nextInt(0, urls.length);
		return urls[index];
	}

	/**
	 * 随机 url
	 * @return
	 */
	public static String url(){
		String [] urls = {
				"https://www.baidu.com/",
				"https://blog.csdn.net/",
				"https://segmentfault.com/",
				"https://www.cnblogs.com/",
				"https://www.jianshu.com/"
		};
		int index = RandomUtils.nextInt(0, urls.length);
		return urls[index];
	}
}

欢迎来我的工具 gitee 上 star ,fork ,你的关注是我最大的动力
sanri-tools-maven

猜你喜欢

转载自blog.csdn.net/sanri1993/article/details/106586725