亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么 Jackson 在重建配置模式以構建 CSV 記錄行時將包含逗號的字符串括起來?

為什么 Jackson 在重建配置模式以構建 CSV 記錄行時將包含逗號的字符串括起來?

慕森卡 2023-12-13 16:53:04
我從存儲庫獲取數據并將其放入 CSV 中。為了建立一條記錄線,我使用杰克遜。我的目標是如果該字段值包含逗號,則用雙引號將該字段(字符串類型)括起來。所以輸出應該是這樣的:some-uuid-value,一些不帶逗號的字符串,SOMETHING,123456,www.some.url 等some-uuid-value,“一些字符串,但帶逗號”,SOMETHING,123456,www.some.url 等一些- uuid-value、一些不帶逗號的字符串、SOMETHING、123456、www.some.url 等我想出了這個代碼:private String toCsvString(EntityCsvRecord entity) {        CsvMapper mapper = new CsvMapper();        CsvSchema schema = mapper.schemaFor(EntityCsvRecord.class).withoutQuoteChar();        if (entity.getName() == null) {            entity.setName("");        }        if (entity.getName().contains(",")) {            String columnName = "name";            int nameColumnIndex = schema.column(columnName).getIndex();            schema = mapper                .configure(CsvGenerator.Feature.STRICT_CHECK_FOR_QUOTING, true)                .schemaFor(EntityCsvRecord.class)                .rebuild()                .replaceColumn(nameColumnIndex, new CsvSchema.Column(nameColumnIndex, columnName))                .build();        }        try {            return mapper.writer(schema).writeValueAsString(entity);        } catch (Exception e) {            ...        }    }但是,我不明白為什么它會這樣工作,我在文檔中找不到任何血統線索。有人能解開這個謎團嗎?
查看完整描述

1 回答

?
ITMISS

TA貢獻1871條經驗 獲得超8個贊

整個技巧是啟用CsvGenerator.Feature.STRICT_CHECK_FOR_QUOTING功能。來自文檔:

確定在確定列值需要引用之前完成多少工作的功能:當設置為 true 時,將進行全面檢查以僅在絕對必要時使用引用;但當為 false 時,會進行更快但更保守的檢查,并且可能對可能不需要的值使用引號。權衡基本上是在最佳/最小引用(true)和更快的處理(false)之間。更快的檢查涉及僅檢查值的前 N 個字符,以及可能的更寬松的檢查。

但請注意,無論設置如何,所有需要引用的值都將是:只是當設置為 false 時,還可以引用其他值(以避免必須進行更昂貴的檢查)。

對于“寬松”(近似、保守)檢查,默認值為 false。

您可以刪除模式和映射器的所有其他配置,并且它將以相同的方式工作。您可以將其簡化為以下代碼:

class CsvEntityGenerator {


? ? private final CsvMapper mapper;

? ? private final CsvSchema schema;


? ? public CsvEntityGenerator(Class clazz) {

? ? ? ? mapper = new CsvMapper();

? ? ? ? mapper.enable(CsvGenerator.Feature.STRICT_CHECK_FOR_QUOTING);


? ? ? ? schema = mapper.schemaFor(clazz).withNullValue("");

? ? }


? ? public String toCsvString(Object entity) throws IOException {

? ? ? ? return mapper.writer(schema).writeValueAsString(entity);

? ? }

}

以及簡單的用法:


CsvEntityGenerator gen = new CsvEntityGenerator(EntityCsvRecord.class);

System.out.print(gen.toCsvString(new EntityCsvRecord("Na,me")));

System.out.print(gen.toCsvString(new EntityCsvRecord(null)));

System.out.print(gen.toCsvString(new EntityCsvRecord("Name")));

印刷:


8b572b1b-17c1-429d-887b-ec9af1c30d05,"Na,me",SOMETHING,123456,www.some.url

e86eacb1-d45e-4614-91bb-45f0d8840ea9,,SOMETHING,123456,www.some.url

e9627c32-6736-44a5-8eb2-7d153f86af20,Name,SOMETHING,123456,www.some.url

正如您所看到的,我們只創建一次CsvMapper并且CsvSchema當我們想要序列化實體時重用它。這是更快的方法。


查看完整回答
反對 回復 2023-12-13
  • 1 回答
  • 0 關注
  • 165 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號