概述
官网: https://github.com/paul-hammant/qdox
依赖: https://mvnrepository.com/artifact/com.github.shalousun/qdox
代码
<!--源码解析 == smartdoc就是用这个进行解析的 -->
<!-- https://mvnrepository.com/artifact/com.github.shalousun/qdox -->
<dependency>
<groupId>com.github.shalousun</groupId>
<artifactId>qdox</artifactId>
<version>2.0.3</version>
</dependency>
二次封装
工具
SourceParseUtil.java
package work.linruchang.lrcutilsweb.util;
import cn.hutool.core.bean.BeanPath;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.stream.CollectorUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.thoughtworks.qdox.JavaProjectBuilder;
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaField;
import com.thoughtworks.qdox.model.JavaSource;
import lombok.SneakyThrows;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 源码解析器
*
* @author LinRuChang
* @version 1.0
* @date 2022/10/08
* @since 1.8
**/
public class SourceParseUtil {
public static enum SourceTypeEnum {
STRING, FILE
}
/**
* 解析Java源码
*
* @param sourceTypeEnum {@code javaSourceContent}的类型
* @param javaSourceContent 源码类型 字符串OR文件
* @return
*/
@SneakyThrows
public static JavaSource readJavaSource(SourceTypeEnum sourceTypeEnum, Object javaSourceContent) {
Assert.notNull(sourceTypeEnum);
switch (sourceTypeEnum) {
case STRING: {
Assert.isTrue(javaSourceContent instanceof String);
String javaSourceContent1 = Convert.toStr(javaSourceContent);
if (StrUtil.isNotBlank(javaSourceContent1)) {
JavaProjectBuilder builder = new JavaProjectBuilder();
return builder.addSource(IoUtil.getReader(IoUtil.toStream(javaSourceContent1.getBytes()), StandardCharsets.UTF_8));
}
break;
}
case FILE: {
Assert.isTrue(javaSourceContent instanceof File);
File javaSourceContentFile = Convert.convert(File.class, javaSourceContent);
if (FileUtil.exist(javaSourceContentFile) && FileUtil.isFile(javaSourceContentFile)) {
JavaProjectBuilder builder = new JavaProjectBuilder();
return builder.addSource(javaSourceContentFile);
}
break;
}
}
return null;
}
/**
* 获取java源码里面的包名
*
* @param javaSourceContent Java源码内容
* @return
*/
public static String getPackageName(String javaSourceContent) {
return Optional.ofNullable(readJavaSource(SourceTypeEnum.STRING, javaSourceContent))
.map(JavaSource::getPackageName)
.orElse(null);
}
/**
* 获取java源码里面的包名
*
* @param javaSourceContentFile Java源码内容文件
* @return
*/
public static String getPackageName(File javaSourceContentFile) {
return Optional.ofNullable(readJavaSource(SourceTypeEnum.FILE, javaSourceContentFile))
.map(JavaSource::getPackageName)
.orElse(null);
}
/**
* 获取JavaBean的字段信息
*
* @param sourceTypeEnum {@code javaSourceContent}的类型
* @param javaSourceContent Java源码内容
* @return
*/
public static List<JavaField> getFirstLevelFieldInfos(SourceTypeEnum sourceTypeEnum, Object javaSourceContent) {
return Optional.ofNullable(readJavaSource(sourceTypeEnum, javaSourceContent))
.map(JavaSource::getClasses)
.orElse(CollUtil.newArrayList())
.stream()
.map(JavaClass::getFields)
.flatMap(List::stream)
.collect(Collectors.toList());
}
/**
* 获取类的全限定名
*
* @param javaClass
* @return
*/
private static String getTypeFullyQualifiedName(JavaClass javaClass) {
return Optional.ofNullable(javaClass)
// .map(javaClassInfo -> StrUtil.join(StrUtil.DOT, ArrayUtil.removeBlank(new String[]{javaClassInfo.getPackageName(), javaClassInfo.getName()})))
.map(javaClassInfo -> {
String typeFullyQualifiedName = javaClass.toString();
if(StrUtil.endWith(typeFullyQualifiedName,"[]")){
typeFullyQualifiedName = StrUtil.format("[L{};", StrUtil.removeSuffix(typeFullyQualifiedName,"[]"));
}
return typeFullyQualifiedName;
})
.orElse(null);
}
/**
* 获取字段的全限定名
*
* @param javaField
* @return
*/
private static String getFieldTypeFullyQualifiedName(JavaField javaField) {
return Optional.ofNullable(javaField)
.map(JavaField::getType)
.map(SourceParseUtil::getTypeFullyQualifiedName)
.orElse(null);
}
/**
* 获取字段信息
*
* @param javaSourceContent 源码内容
* @return key字段名 value字段数据类型(全限定名)
*/
public static Map<String, String> getFirstLevelFields(String javaSourceContent) {
return getFirstLevelFieldInfos(SourceTypeEnum.STRING, javaSourceContent).stream()
.collect(CollectorUtil.toMap(JavaField::getName, SourceParseUtil::getFieldTypeFullyQualifiedName, (v1, v2) -> v2));
}
/**
* 获取字段信息
*
* @param javaSourceContentFile 源码内容文件
* @return key字段名 value字段数据类型(全限定名)
*/
public static Map<String, String> getFirstLevelFields(File javaSourceContentFile) {
return getFirstLevelFieldInfos(SourceTypeEnum.FILE, javaSourceContentFile).stream()
.collect(CollectorUtil.toMap(JavaField::getName, SourceParseUtil::getFieldTypeFullyQualifiedName, (type1, type2) -> type1));
}
/**
* 获取字段信息
*
* @param javaSourceContent 源码内容文件
* @return key字段名 value字段数据类型
*/
public static Map<String, Class> getFirstLevelField2Types(String javaSourceContent) {
return MapUtil.emptyIfNull(getFirstLevelFields(javaSourceContent)).entrySet()
.stream()
.collect(CollectorUtil.toMap(Map.Entry::getKey, mapEntry -> {
return EnhanceClassUtil.getType(mapEntry.getValue());
}, (ftype1, ftype2) -> ftype2));
}
/**
* 获取字段信息
*
* @param javaSourceContent 源码内容文件
* @return key字段名 value字段数据类型
*/
public static Map<String, Class> getFirstLevelField2Types(File javaSourceContent) {
return MapUtil.emptyIfNull(getFirstLevelFields(javaSourceContent)).entrySet()
.stream()
.collect(CollectorUtil.toMap(Map.Entry::getKey, mapEntry -> {
return EnhanceClassUtil.getType(mapEntry.getValue());
}, (ftype1, ftype2) -> ftype2));
}
/**
* 获取当前类所有自定义类信息
*
* @param javaSourceContent
* @return
*/
public static Set<JavaClass> getCustomAllClass(SourceTypeEnum sourceTypeEnum, Object javaSourceContent) {
Set<JavaClass> result = CollUtil.newHashSet();
JavaSource javaSource = readJavaSource(sourceTypeEnum, javaSourceContent);
if (javaSource != null) {
JavaClass currentJavaClass = javaSource.getClasses().get(0);
getCustomAllClass(currentJavaClass, result);
}
return result;
}
/**
* 获取当前类所有自定义类信息
*
* @return
*/
private static void getCustomAllClass(JavaClass currentJavaClass, Set<JavaClass> resultClass) {
if (currentJavaClass == null) {
return;
}
boolean addFlag = resultClass.add(currentJavaClass);
if (addFlag) {
currentJavaClass.getNestedClasses().stream()
.forEach(javaClass -> getCustomAllClass(javaClass, resultClass));
}
}
/**
* 是否含循环引用的Bean(即javaClass1中有字段是javaClass2数据类型,javaClass2中有字段是javaClass1类型)
*
* @param javaClass1
* @param javaClass2
* @return
*/
public static boolean isCircularreferenceFlag(JavaClass javaClass1, JavaClass javaClass2) {
if (ObjectUtil.hasNull(javaClass1, javaClass2)) {
return false;
}
boolean fieldsFlag1 = javaClass1.getFields().stream()
.anyMatch(javaField -> javaClass2.equals(javaField.getType()));
boolean fieldsFlag2 = javaClass2.getFields().stream()
.anyMatch(javaField -> javaClass1.equals(javaField.getType()));
return fieldsFlag1 && fieldsFlag2;
}
/**
* 获取当前类代码的Bean结构
*
* @param sourceTypeEnum 代码类型
* @param javaSourceContent 代码
* @return key字段名 value字段类型
*/
public static Map<String, Object> getBeanFieldStructure(SourceTypeEnum sourceTypeEnum, Object javaSourceContent) {
return Optional.ofNullable(readJavaSource(sourceTypeEnum, javaSourceContent))
.map(javaSource -> {
JavaClass currentJavaClass = javaSource.getClasses().get(0);
return getBeanFieldStructure(currentJavaClass, null, MapUtil.newHashMap());
}).orElse(MapUtil.empty());
}
/**
* 获取当前类代码的Bean结构
* @param javaClass 当前类
* @param parentKeyName 父类
* @param result 结构
* @return key字段名 value字段类型
*/
private static Map<String, Object> getBeanFieldStructure(JavaClass javaClass, String parentKeyName, Map<String, Object> result) {
javaClass.getFields().stream().forEach(javaField -> {
String nextParentKeyName = StrUtil.format("{}{}.", StrUtil.blankToDefault(parentKeyName, StrUtil.EMPTY), javaField.getName());
JavaClass currentFieldType = javaField.getType();
if (EnhanceClassUtil.isNotBeanFieldJavaType(getFieldTypeFullyQualifiedName(javaField))) {
// 非普通类型字段
if (isCircularreferenceFlag(javaClass, currentFieldType)) {
currentFieldType.getFields()
.stream()
.forEach(javaField1 -> {
String nextnextParentKeyName = StrUtil.format("{}{}.", nextParentKeyName, javaField1.getName());
// if(javaField1.getType().isInner()) {
if (EnhanceClassUtil.isNotBeanFieldJavaType(getFieldTypeFullyQualifiedName(javaField1))) {
if (!javaField1.getType().equals(javaClass)) {
getBeanFieldStructure(javaField1.getType(), nextnextParentKeyName, result);
}
} else {
String fieldTypeFullyQualifiedName = getFieldTypeFullyQualifiedName(javaField1);
BeanPath.create(nextnextParentKeyName).set(result, EnhanceClassUtil.getType(fieldTypeFullyQualifiedName));
}
});
// 普通类型字段
} else {
getBeanFieldStructure(currentFieldType, nextParentKeyName, result);
}
} else {
String fieldTypeFullyQualifiedName = getFieldTypeFullyQualifiedName(javaField);
Class type = EnhanceClassUtil.getType(fieldTypeFullyQualifiedName);
BeanPath.create(nextParentKeyName).set(result, type);
}
});
return result;
}
}
测试
UserBindInfo.java
package work.linruchang.bean;
import lombok.Data;
import lombok.ToString;
import javax.persistence.*;
import java.util.Date;
import java.util.List;
@Entity
@NamedQueries({
})
@Table(name="ct_user_bind_info")
public class UserBindInfo extends BaseEntity {
private static final long serialVersionUID = 4370057088332727818L;
String[] names2;
List<String> names;
private User user;
private Landlord landlord;
private String userMobile;
private String areaCode;
private String regionCode;
private String mscCode;
private String onu; //线路编码
//===========六元组信息===============
private String slot;
private String subslot;
private String port;
private String ctNasIp;
private String ctXpi;
private String ctXci;
//==========================
private Long landlordId;
private String landlordMobile;
private Long buildingId;
private Date createTime;
private Date updateTime;
//该用户最后绑定线路标识 1:最后绑定,0:不是最后绑定
private String userLastBind;
/**
* 定时任务ReadCtbbBindTimer根据六元组还是五元组信息查到的房东视图 数据库存储值【T5、T6】
*
* 其他存储值代表暂不清楚
*/
private String matchFlag;
@Column(name="room_number")
private String roomNumber;//房间编号
@Entity
@NamedQueries({
})
@Table(name = "v_user")
@Data
@ToString(callSuper = true)
public class User extends BaseEntity {
private static final long serialVersionUID = -1591685848660375009L;
private String name;
private String username;
private String password;
private String birthday;
private String email;
private String phone;
private String gender;
/**
* -1未开通激活 0正常 1是加锁
* 参考{Constants#USER_STATUS_IS_LOCKED}等状态码
*/
private Integer status;
private Date regDate;
private Date loginDate;
private Date updateDate;
/**
* 角色主键ID
*/
private Long userRole;
/**
* 市编码
*/
private String areaCode; // 地区代码 (新增)
/**
* 具体在市哪个区/县编码
*/
private String regionCode;
private String mscCode;
/**
* 近期使用密码1
*/
private String pass1;
/**
* 近期使用密码2
*/
private String pass2;
/**
* 近期更换密码时间
*/
private Date passUpdateDate;
}
@Entity
@NamedQueries({
})
@Table(name="ct_landlord_reg_info")
@Data
public class Landlord extends BaseEntity {
@Entity
@Table(name = "ct_ctb_line_info")
@NamedQueries({
})
public class CtbLineInfo extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 对应楼栋ID
*/
@Column(name = "building_id")
private Long buildingId;
@Column(name = "test_account")
private String testAccount;
private String password;
/**
* 记录创建时间
*/
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "create_time")
private Date createTime;
/**
* 记录更新时间
*/
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "update_time")
private Date updateTime;
/**
* 占用资源、线路编码 多个同一个六元组可能绑定不一样的主线编码
*/
private String onu;
/**
* 局向
*/
@Column(name = "ct_direction")
private String direction;
/**
* 局向编码
*/
@Column(name = "ct_direction_code")
private String directionCode;
/**
* ===========六元组信息================
*/
/**
* 接入服务器IP
*/
@Column(name = "ct_nas_ip")
private String ctNasIp;
/**
* xci
*/
@Column(name = "ct_xci")
private String ctXci;
/**
* xpi
*/
@Column(name = "ct_xpi")
private String ctXpi;
/**
* 端口
*/
private String port;
/**
* 槽位
*/
private String slot;
/**
* 子槽位
*/
private String subslot;
/**
* ===========================
*/
/**
* 备注
*/
private String mark;
/**
* 揽装人工号 == CRM的销售渠道编码
*/
private String decorateNum;
/**
* 标准地址ID
*/
private String addressId;
/**
* 标准地址名称
*/
@Column(name = "address_name")
private String addressName;
/**
* 设备编码
*/
private String macCode;
/**
* 地市编码
*/
private String areaCode;
/**
* 区县编码
*/
@Column(name = "region_code")
private String regionCode;
/**
* 营服编码
*/
private String mscCode;
/**
* 房东ID
*/
private Long landlordId;
/**
* 快捷送主线时的订购方式
* 0:默认1线多号
* 1:1线1号
*
* 参考{ Constants#CCLI_TYPE_MANY}
*/
private String type;
/**
*
* 【已不使用】
* 是否强制六元组信息不随定时任务ReadCtbbBindTimer发生变更
* 数据库值:1true 0false 默认0
*/
@Column(name = "forced_sync_flag")
private boolean forcedSyncFlag = false;
/**
* 房间信息
*/
//private String houseInfo;
/**
* 逻辑删除 == 待删除 == 记得删
*
* 1逻辑删除 0正常显示
*/
//Integer isDel;
@Transient
private Long houseId;// 翼乐居房间号
@Transient
private String flatName;// 翼乐居房间号
/**
* 线路类型
* { Constants#LINE_TYPE_APARTMENT}
*/
@Transient
private String lineType;
/**
* 揽装人姓名
*/
@Transient
private String decorateName;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDecorateName() {
return decorateName;
}
public void setDecorateName(String decorateName) {
this.decorateName = decorateName;
}
public String getLineType() {
return lineType;
}
public void setLineType(String lineType) {
this.lineType = lineType;
}
public CtbLineInfo() {
}
public String getFlatName() {
return flatName;
}
public void setFlatName(String flatName) {
this.flatName = flatName;
}
public Long getHouseId() {
return houseId;
}
public void setHouseId(Long houseId) {
this.houseId = houseId;
}
public boolean getForcedSyncFlag() {
return forcedSyncFlag;
}
public void setForcedSyncFlag(boolean forcedSyncFlag) {
this.forcedSyncFlag = forcedSyncFlag;
}
public Long getBuildingId() {
return this.buildingId;
}
public String getDirection() {
return direction;
}
public void setDirection(String direction) {
this.direction = direction;
}
public String getDirectionCode() {
return directionCode;
}
public String getMacCode() {
return macCode;
}
public void setMacCode(String macCode) {
this.macCode = macCode;
}
public void setDirectionCode(String directionCode) {
this.directionCode = directionCode;
}
public String getSlot() {
return slot;
}
public void setSlot(String slot) {
this.slot = slot;
}
public String getSubslot() {
return subslot;
}
public void setSubslot(String subslot) {
this.subslot = subslot;
}
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port;
}
public String getTestAccount() {
return testAccount;
}
public void setTestAccount(String testAccount) {
this.testAccount = testAccount;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public void setBuildingId(Long buildingId) {
this.buildingId = buildingId;
}
public Date getCreateTime() {
return this.createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getCtNasIp() {
return this.ctNasIp;
}
public void setCtNasIp(String ctNasIp) {
this.ctNasIp = ctNasIp;
}
public String getCtXci() {
return this.ctXci;
}
public void setCtXci(String ctXci) {
this.ctXci = ctXci;
}
public String getCtXpi() {
return this.ctXpi;
}
public void setCtXpi(String ctXpi) {
this.ctXpi = ctXpi;
}
public Date getUpdateTime() {
return this.updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public String getOnu() {
return onu;
}
public void setOnu(String onu) {
this.onu = onu;
}
public String getMark() {
return mark;
}
public void setMark(String mark) {
this.mark = mark;
}
public String getDecorateNum() {
return decorateNum;
}
public void setDecorateNum(String decorateNum) {
this.decorateNum = decorateNum;
}
public String getAddressId() {
return addressId;
}
public void setAddressId(String addressId) {
this.addressId = addressId;
}
public String getAddressName() {
return addressName;
}
public void setAddressName(String addressName) {
this.addressName = addressName;
}
public String getAreaCode() {
return areaCode;
}
public void setAreaCode(String areaCode) {
this.areaCode = areaCode;
}
public String getRegionCode() {
return regionCode;
}
public void setRegionCode(String regionCode) {
this.regionCode = regionCode;
}
public String getMscCode() {
return mscCode;
}
public void setMscCode(String mscCode) {
this.mscCode = mscCode;
}
public Long getLandlordId() {
return landlordId;
}
public void setLandlordId(Long landlordId) {
this.landlordId = landlordId;
}
//public String getHouseInfo() {
// return houseInfo;
//}
//
//public void setHouseInfo(String houseInfo) {
// this.houseInfo = houseInfo;
//}
@Override
public String toString() {
return "CtbLineInfo{" +
"buildingId=" + buildingId +
", testAccount='" + testAccount + '\'' +
", password='" + password + '\'' +
", createTime=" + createTime +
", updateTime=" + updateTime +
", onu='" + onu + '\'' +
", direction='" + direction + '\'' +
", directionCode='" + directionCode + '\'' +
", ctNasIp='" + ctNasIp + '\'' +
", ctXci='" + ctXci + '\'' +
", ctXpi='" + ctXpi + '\'' +
", port='" + port + '\'' +
", slot='" + slot + '\'' +
", subslot='" + subslot + '\'' +
", mark='" + mark + '\'' +
", decorateNum='" + decorateNum + '\'' +
", addressId='" + addressId + '\'' +
", addressName='" + addressName + '\'' +
", macCode='" + macCode + '\'' +
", areaCode='" + areaCode + '\'' +
", regionCode='" + regionCode + '\'' +
", mscCode='" + mscCode + '\'' +
", landlordId=" + landlordId +
", type='" + type + '\'' +
", forcedSyncFlag=" + forcedSyncFlag +
", houseId=" + houseId +
", flatName='" + flatName + '\'' +
", lineType='" + lineType + '\'' +
", decorateName='" + decorateName + '\'' +
'}';
}
}
/**
*
*/
private static final long serialVersionUID = 173935594147564367L;
private UserBindInfo userBindInfo;
private OnuMapper onuMapper;
private String name;
/**
* 房东姓名
*/
@Column(name = "user_name")
private String userName;
/**
* 房东手机号
*/
@Column(name = "user_mobile")
private String userMobile;
/**
* 身份信息
*/
@Column(name = "user_id_num")
private String userIdNum;
/**
* 身份信息
*/
@Column(name = "certificates_type")
private String certificatesType;
@Column(name = "create_time")
private Date createTime;
@Column(name = "update_time")
private Date updateTime;
@Column(name = "status")
private String status;
/**
* 地市编码
*/
private String areaCode;
/**
* 区县编码
*/
private String regionCode;
/**
* 备注
*/
private String mark;
/**
* 所属代理商ID
*/
@Column(name="agent_id")
private Long agentId;
/**
* 翼支付账号
*/
private String easyPayAccount;
/**
* 复通次数 月份+次数+字典次数 例子:2018-08;3;30
*/
private String reopenTime;
}
public String getUserMobile() {
return userMobile;
}
public void setUserMobile(String userMobile) {
this.userMobile = userMobile;
}
public String getRegionCode() {
return regionCode;
}
public void setRegionCode(String regionCode) {
this.regionCode = regionCode;
}
public String getCtNasIp() {
return ctNasIp;
}
public void setCtNasIp(String ctNasIp) {
this.ctNasIp = ctNasIp;
}
public String getCtXpi() {
return ctXpi;
}
public void setCtXpi(String ctXpi) {
this.ctXpi = ctXpi;
}
public String getCtXci() {
return ctXci;
}
public void setCtXci(String ctXci) {
this.ctXci = ctXci;
}
public Long getLandlordId() {
return landlordId;
}
public void setLandlordId(Long landlordId) {
this.landlordId = landlordId;
}
public String getLandlordMobile() {
return landlordMobile;
}
public void setLandlordMobile(String landlordMobile) {
this.landlordMobile = landlordMobile;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
public String getOnu() {
return onu;
}
public void setOnu(String onu) {
this.onu = onu;
}
public String getSlot() {
return slot;
}
public void setSlot(String slot) {
this.slot = slot;
}
public String getSubslot() {
return subslot;
}
public void setSubslot(String subslot) {
this.subslot = subslot;
}
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port;
}
public String getAreaCode() {
return areaCode;
}
public void setAreaCode(String areaCode) {
this.areaCode = areaCode;
}
public String getMscCode() {
return mscCode;
}
public void setMscCode(String mscCode) {
this.mscCode = mscCode;
}
public String getUserLastBind() {
return userLastBind;
}
public void setUserLastBind(String userLastBind) {
this.userLastBind = userLastBind;
}
public Long getBuildingId() {
return buildingId;
}
public void setBuildingId(Long buildingId) {
this.buildingId = buildingId;
}
public String getMatchFlag() {
return matchFlag;
}
public void setMatchFlag(String matchFlag) {
this.matchFlag = matchFlag;
}
public String getRoomNumber() {
return roomNumber;
}
public void setRoomNumber(String roomNumber) {
this.roomNumber = roomNumber;
}
@Override
public String toString() {
return "UserBindInfo{" +
"userMobile='" + userMobile + '\'' +
", areaCode='" + areaCode + '\'' +
", regionCode='" + regionCode + '\'' +
", mscCode='" + mscCode + '\'' +
", onu='" + onu + '\'' +
", slot='" + slot + '\'' +
", subslot='" + subslot + '\'' +
", port='" + port + '\'' +
", ctNasIp='" + ctNasIp + '\'' +
", ctXpi='" + ctXpi + '\'' +
", ctXci='" + ctXci + '\'' +
", landlordId=" + landlordId +
", landlordMobile='" + landlordMobile + '\'' +
", buildingId=" + buildingId +
", createTime=" + createTime +
", updateTime=" + updateTime +
", userLastBind='" + userLastBind + '\'' +
", matchFlag='" + matchFlag + '\'' +
", roomNumber='" + roomNumber + '\'' +
'}';
}
}
Test.java
@Test
public void otherTest2() {
File sourceFile = FileUtil.file("G:\\IDEA2021.3\\workspace\\lrc\\lrctool\\src\\test\\java\\work\\linruchang\\bean\\UserBindInfo.java");
Map<String, Object> beanFieldStructure = SourceParseUtil.getBeanFieldStructure(SourceParseUtil.SourceTypeEnum.FILE, sourceFile);;
beanFieldStructure.forEach(Console::log);
}