Java 写入 Multi-VCard 时出现问题
Java issues writing Multi-VCard
美好的一天
我正在尝试将地址簿导出到单个多 vcard 中,以便将其与 Gigaset N520-IP Pro 一起使用
以下是我在Gigaset手机中创建的一个示例条目,并使用webgui导出功能将其导出:
BEGIN:VCARD
VERSION:2.1
N:Bob;Bobbington
TEL;HOME:00412345689
TEL;WORK:00419876543
TEL;CELL:004112345432
END:VCARD
BEGIN:VCARD
VERSION:2.1
N:NotBob;NotBobbington
TEL;HOME:00412345689
TEL;WORK:00419876543
TEL;CELL:004112345432
END:VCARD
BEGIN:VCARD....
我将其用作生成导入所需的特定 VCard 的模板,但每当我尝试导入它时,它只接受整个 vcard 作为一个人,即使其中有 20 个条目。
我的条目如下所示:
BEGIN:VCARD
VERSION:2.1
N:Max;Mustermann
TEL;HOME:00411234578
TEL;WORK:00411234567
TEL;CELL:00411234590
END:VCARD
BEGIN:VCARD
VERSION:2.1
N:MHUEUEx;MusterHEHEmann
TEL;HOME:00411234578
TEL;WORK:00411234567
TEL;CELL:00411234590
END:VCARD
我看不出我的和导出的 vcard 之间的视觉差异。
如果我将我的条目复制到另一个 vcard 中,它会立即停止工作。
但是,如果我复制工作 vcard 中的现有条目,vcard 仍然有效。
我想整个文件都存在某种编码问题。
我还检查了 VCard Wiki 站点以查找我可能犯的错误,并尝试了一些修复。
我试过了:
SafeCharing 仅将所有字符串转换为字母 (a-z && A-Z)(数字除外)
暂时将数字中的 + 替换为 00。
将 VCARD 字符串缩减为仅 ASCII。
使用不同的行分隔符 ("\n, \r\n", System.lineSeparator())
系统数据:
OS:Centos 6.8(最终版)
Java-版本:1.8.0_102-b14 (x64)
现在,这是我的实际代码:
//Code for Address book fetching would be here
log.debug("Received : " + Addressbook.size());
File ExportFile = new File(ExportFilePath);
if(ExportFile.exists())
{
ExportFile.delete();
}
ExportFile.createNewFile();
log.debug("Writing VCards to File: " + ExportFile.getAbsolutePath());
FileWriter FW = new FileWriter(ExportFile);
Map<String, DataEntry> Properties = null;
String homephone="";
String phone="";
String mobile="";
String firstname="";
String lastname="";
StringBuilder SB = null;
String Fix="";
for(AddressbookContact AC : Addressbook)
{
log.debug("Writing: " + AC.getName());
Properties = AC.getContactProperties();
SB = new StringBuilder();
SB.append("BEGIN:VCARD");
SB.append(System.lineSeparator());
SB.append("VERSION:2.1");
SB.append(System.lineSeparator());
firstname=NameFilter(AC.getFirstname());
lastname=NameFilter(AC.getFamilyname());
SB.append("N:"+firstname+";"+lastname);
SB.append(System.lineSeparator());
homephone= Properties.get("homephone").getValue();
log.debug("Homephone: " + homephone);
if(homephone.startsWith("+")) //Test only, to exlucde existing + as an errorsource
{
//TODO: If + was source of error, write proper regex replace function
homephone="00"+homephone.substring(1, homephone.length());
}
log.debug("Filtered: " + homephone);
phone = Properties.get("phone").getValue();
log.debug("Phone: " + phone);
if(phone.startsWith("+"))
{
phone="00"+phone.substring(1, phone.length());
}
log.debug("Filtered: " +phone);
mobile= Properties.get("mobile").getValue();
log.debug("Mobile: " + mobile);
if(mobile.startsWith("+"))
{
mobile ="00"+mobile.substring(1, mobile.length());
}
log.debug("Filtered: " + mobile);
if(!homephone.isEmpty())
{
SB.append("TEL;HOME:"+homephone);
SB.append(System.lineSeparator());
}
if(!phone.isEmpty())
{
SB.append("TEL;WORK:"+phone);
SB.append(System.lineSeparator());
}
if(!mobile.isEmpty())
{
SB.append("TEL;CELL:"+mobile);
SB.append(System.lineSeparator());
}
SB.append("END:VCARD");
SB.append(System.lineSeparator());
SB.append(System.lineSeparator());
Fix = SB.toString();
Fix = Fix.replaceAll("[^\u0000-\uFFFF]", ""); //ASCII only
FW.write(Fix);
}
log.debug("Done!");
FW.close();
}
String NameFilter(String Entry)
{
String safeChar="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ";
char[] allowed = safeChar.toCharArray();
char[] charArray = Entry.toCharArray();
StringBuilder Result = new StringBuilder();
for (char c : charArray)
{
for (char a : allowed)
{
if(c==a) Result.append(a);
}
}
return Result.toString();
}
如何调试此类问题?
此致Fabian95qw
删除 vCard 之间的空行。
我想通了,看到的导出 VCard 与实际 vcard 版本 2.1 不一致
所以我尝试使用 ezvcard 生成 multivcard。现在完全 vcard 版本 2.1 符合 multivcard 工作。
log.debug("Writing VCards to File: " + ExportFile.getAbsolutePath());
FileWriter FW = new FileWriter(ExportFile);
VCardWriter VCW = new VCardWriter(FW, VCardVersion.V2_1);
VCard VC = null;
StructuredName SN = null;
Telephone T = null;
Map<String, DataEntry> Properties = null;
String homephone="";
String phone="";
String mobile="";
String firstname="";
String lastname="";
for(AddressbookContact AC : Addressbook)
{
log.debug("Writing: " + AC.getName());
Properties = AC.getContactProperties();
firstname=NameFilter(AC.getFirstname());
lastname=NameFilter(AC.getFamilyname());
if(firstname.isEmpty() && lastname.isEmpty())
{
firstname = AC.getCompany();
}
VC = new VCard();
SN = new StructuredName();
SN.setFamily(lastname);
SN.setGiven(firstname);
VC.setStructuredName(SN);
homephone= Properties.get("homephone").getValue();
phone = Properties.get("phone").getValue();
mobile= Properties.get("mobile").getValue();
if(!homephone.isEmpty())
{
T = new Telephone(homephone);
T.addType(TelephoneType.HOME);
VC.addTelephoneNumber(T);
}
if(!phone.isEmpty())
{
T = new Telephone(phone);
T.addType(TelephoneType.WORK);
VC.addTelephoneNumber(T);
}
if(!mobile.isEmpty())
{
T = new Telephone(mobile);
T.addType(TelephoneType.CELL);
VC.addTelephoneNumber(T);
}
VCW.write(VC);
}
VCW.close();
VCard 文件如下所示:
BEGIN:VCARD
VERSION:2.1
N:Testinator;Testinator;;;
TEL;WORK:101
X-PRODID:ezvcard 0.9.0
END:VCARD
BEGIN:VCARD
VERSION:2.1
N:Administrator;Test;;;
TEL;WORK:100
X-PRODID:ezvcard 0.9.0
END:VCARD
~ 问题已解决
此致
Fabian95qw
美好的一天
我正在尝试将地址簿导出到单个多 vcard 中,以便将其与 Gigaset N520-IP Pro 一起使用
以下是我在Gigaset手机中创建的一个示例条目,并使用webgui导出功能将其导出:
BEGIN:VCARD
VERSION:2.1
N:Bob;Bobbington
TEL;HOME:00412345689
TEL;WORK:00419876543
TEL;CELL:004112345432
END:VCARDBEGIN:VCARD
VERSION:2.1
N:NotBob;NotBobbington
TEL;HOME:00412345689
TEL;WORK:00419876543
TEL;CELL:004112345432
END:VCARDBEGIN:VCARD....
我将其用作生成导入所需的特定 VCard 的模板,但每当我尝试导入它时,它只接受整个 vcard 作为一个人,即使其中有 20 个条目。
我的条目如下所示:
BEGIN:VCARD
VERSION:2.1
N:Max;Mustermann
TEL;HOME:00411234578
TEL;WORK:00411234567
TEL;CELL:00411234590
END:VCARDBEGIN:VCARD
VERSION:2.1
N:MHUEUEx;MusterHEHEmann
TEL;HOME:00411234578
TEL;WORK:00411234567
TEL;CELL:00411234590
END:VCARD
我看不出我的和导出的 vcard 之间的视觉差异。
如果我将我的条目复制到另一个 vcard 中,它会立即停止工作。
但是,如果我复制工作 vcard 中的现有条目,vcard 仍然有效。
我想整个文件都存在某种编码问题。
我还检查了 VCard Wiki 站点以查找我可能犯的错误,并尝试了一些修复。
我试过了:
SafeCharing 仅将所有字符串转换为字母 (a-z && A-Z)(数字除外)
暂时将数字中的 + 替换为 00。
将 VCARD 字符串缩减为仅 ASCII。
使用不同的行分隔符 ("\n, \r\n", System.lineSeparator())
系统数据:
OS:Centos 6.8(最终版)
Java-版本:1.8.0_102-b14 (x64)
现在,这是我的实际代码:
//Code for Address book fetching would be here
log.debug("Received : " + Addressbook.size());
File ExportFile = new File(ExportFilePath);
if(ExportFile.exists())
{
ExportFile.delete();
}
ExportFile.createNewFile();
log.debug("Writing VCards to File: " + ExportFile.getAbsolutePath());
FileWriter FW = new FileWriter(ExportFile);
Map<String, DataEntry> Properties = null;
String homephone="";
String phone="";
String mobile="";
String firstname="";
String lastname="";
StringBuilder SB = null;
String Fix="";
for(AddressbookContact AC : Addressbook)
{
log.debug("Writing: " + AC.getName());
Properties = AC.getContactProperties();
SB = new StringBuilder();
SB.append("BEGIN:VCARD");
SB.append(System.lineSeparator());
SB.append("VERSION:2.1");
SB.append(System.lineSeparator());
firstname=NameFilter(AC.getFirstname());
lastname=NameFilter(AC.getFamilyname());
SB.append("N:"+firstname+";"+lastname);
SB.append(System.lineSeparator());
homephone= Properties.get("homephone").getValue();
log.debug("Homephone: " + homephone);
if(homephone.startsWith("+")) //Test only, to exlucde existing + as an errorsource
{
//TODO: If + was source of error, write proper regex replace function
homephone="00"+homephone.substring(1, homephone.length());
}
log.debug("Filtered: " + homephone);
phone = Properties.get("phone").getValue();
log.debug("Phone: " + phone);
if(phone.startsWith("+"))
{
phone="00"+phone.substring(1, phone.length());
}
log.debug("Filtered: " +phone);
mobile= Properties.get("mobile").getValue();
log.debug("Mobile: " + mobile);
if(mobile.startsWith("+"))
{
mobile ="00"+mobile.substring(1, mobile.length());
}
log.debug("Filtered: " + mobile);
if(!homephone.isEmpty())
{
SB.append("TEL;HOME:"+homephone);
SB.append(System.lineSeparator());
}
if(!phone.isEmpty())
{
SB.append("TEL;WORK:"+phone);
SB.append(System.lineSeparator());
}
if(!mobile.isEmpty())
{
SB.append("TEL;CELL:"+mobile);
SB.append(System.lineSeparator());
}
SB.append("END:VCARD");
SB.append(System.lineSeparator());
SB.append(System.lineSeparator());
Fix = SB.toString();
Fix = Fix.replaceAll("[^\u0000-\uFFFF]", ""); //ASCII only
FW.write(Fix);
}
log.debug("Done!");
FW.close();
}
String NameFilter(String Entry)
{
String safeChar="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ";
char[] allowed = safeChar.toCharArray();
char[] charArray = Entry.toCharArray();
StringBuilder Result = new StringBuilder();
for (char c : charArray)
{
for (char a : allowed)
{
if(c==a) Result.append(a);
}
}
return Result.toString();
}
如何调试此类问题?
此致Fabian95qw
删除 vCard 之间的空行。
我想通了,看到的导出 VCard 与实际 vcard 版本 2.1 不一致
所以我尝试使用 ezvcard 生成 multivcard。现在完全 vcard 版本 2.1 符合 multivcard 工作。
log.debug("Writing VCards to File: " + ExportFile.getAbsolutePath());
FileWriter FW = new FileWriter(ExportFile);
VCardWriter VCW = new VCardWriter(FW, VCardVersion.V2_1);
VCard VC = null;
StructuredName SN = null;
Telephone T = null;
Map<String, DataEntry> Properties = null;
String homephone="";
String phone="";
String mobile="";
String firstname="";
String lastname="";
for(AddressbookContact AC : Addressbook)
{
log.debug("Writing: " + AC.getName());
Properties = AC.getContactProperties();
firstname=NameFilter(AC.getFirstname());
lastname=NameFilter(AC.getFamilyname());
if(firstname.isEmpty() && lastname.isEmpty())
{
firstname = AC.getCompany();
}
VC = new VCard();
SN = new StructuredName();
SN.setFamily(lastname);
SN.setGiven(firstname);
VC.setStructuredName(SN);
homephone= Properties.get("homephone").getValue();
phone = Properties.get("phone").getValue();
mobile= Properties.get("mobile").getValue();
if(!homephone.isEmpty())
{
T = new Telephone(homephone);
T.addType(TelephoneType.HOME);
VC.addTelephoneNumber(T);
}
if(!phone.isEmpty())
{
T = new Telephone(phone);
T.addType(TelephoneType.WORK);
VC.addTelephoneNumber(T);
}
if(!mobile.isEmpty())
{
T = new Telephone(mobile);
T.addType(TelephoneType.CELL);
VC.addTelephoneNumber(T);
}
VCW.write(VC);
}
VCW.close();
VCard 文件如下所示:
BEGIN:VCARD
VERSION:2.1
N:Testinator;Testinator;;;
TEL;WORK:101
X-PRODID:ezvcard 0.9.0
END:VCARD
BEGIN:VCARD
VERSION:2.1
N:Administrator;Test;;;
TEL;WORK:100
X-PRODID:ezvcard 0.9.0
END:VCARD
~ 问题已解决
此致
Fabian95qw