首页 > 解决方案 > YAMLException:不允许使用特殊字符

问题描述

我正在尝试读取 yml 文件并将其转换为对象以在 yml 文件中进行更改,但是在 linux 服务器中使用 ISO_8859_1 时在转换时出现以下异常。

例外:

Caused by: unacceptable code point 'Â' (0x92) special characters are not allowed
in "'reader'", position 950
        at org.yaml.snakeyaml.reader.StreamReader.update(StreamReader.java:211)
        at org.yaml.snakeyaml.reader.StreamReader.ensureEnoughData(StreamReader.java:176)
        at org.yaml.snakeyaml.reader.StreamReader.peek(StreamReader.java:136)
        at org.yaml.snakeyaml.scanner.ScannerImpl.scanToNextToken(ScannerImpl.java:1185)
        at org.yaml.snakeyaml.scanner.ScannerImpl.fetchMoreTokens(ScannerImpl.java:287)
        at org.yaml.snakeyaml.scanner.ScannerImpl.checkToken(ScannerImpl.java:227)
        at org.yaml.snakeyaml.parser.ParserImpl$ParseBlockMappingKey.produce(ParserImpl.java:558)
        at org.yaml.snakeyaml.parser.ParserImpl.peekEvent(ParserImpl.java:158)
        at org.yaml.snakeyaml.parser.ParserImpl.getEvent(ParserImpl.java:168)
        at com.fasterxml.jackson.dataformat.yaml.YAMLParser.nextToken(YAMLParser.java:355)
        ... 43 more


com.fasterxml.jackson.dataformat.yaml.snakeyaml.error.YAMLException: special characters are not allowed
 at [Source: (StringReader); line: 165, column: 40]
        at com.fasterxml.jackson.dataformat.yaml.snakeyaml.error.YAMLException.from(YAMLException.java:25)
        at com.fasterxml.jackson.dataformat.yaml.YAMLParser.nextToken(YAMLParser.java:361)
        at com.fasterxml.jackson.core.JsonParser.nextFieldName(JsonParser.java:825)
        at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.mapObject(UntypedObjectDeserializer.java:896)
        at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.deserialize(UntypedObjectDeserializer.java:654)
        at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.mapObject(UntypedObjectDeserializer.java:895)
        at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.deserialize(UntypedObjectDeserializer.java:654)
        at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.mapObject(UntypedObjectDeserializer.java:871)
        at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.deserialize(UntypedObjectDeserializer.java:654)
        at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.mapObject(UntypedObjectDeserializer.java:895)
        at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.deserialize(UntypedObjectDeserializer.java:654)
        at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4014)
        at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3005)

代码摘录:

StringBuilder contentBuilder = new StringBuilder();
String originalFile = "..path";
try (Stream<String> stream = java.nio.file.Files.lines(Paths.get(originalFile), StandardCharsets.ISO_8859_1)) {
            stream.forEach(s -> contentBuilder.append(s).append("\n"));
        }
        
        Object obj = yamlReader.readValue(contentBuilder.toString(), Object.class); 

yaml内容:

---
spring:
  application:
    name: "DGL-SVC-V-AccountRenewalCD"
cdr:
  enable4IPB: true
  mislogging:
    enabled: true
  paymentFrequency:
    cdUpdate:
      monthly: 1
      endOfTerm: 2
    cdDetails:
      monthly: 0
      endOfTerm: 5
  enable4CPB: false
  enableRetirementCDRenewal: true
  interestPaymentApplicationId: "CA"
  interestDistributionMethod:
    payToAffiliate: 1
    redeposit: 0
  addExternalAccounts: false
  invalidIPBTerms: "1,2"
ccp:
  logger:
    ids:
      templateProperties:
        CDRENEWAL: "com.ccp.logging.ids.formatter.JFPIDSMapper||event-type-ccpids-template-self.ftl"
      emsconnector:
        communication: "jms"
      loggerImplementation: "emsConnector"
hystrix:
  threadpool:
    getCDRatesThreadPoolKey:
      maxQueueSize: 5
      coreSize: 40
      maximumSize: 60
      allowMaximumSizeToDivergeFromCoreSize: true
    getCustomerInfoThreadPoolKey:
      maxQueueSize: 5
      coreSize: 40
      maximumSize: 60
      allowMaximumSizeToDivergeFromCoreSize: true
    validateInternalFundTransferThreadPoolKey:
      maxQueueSize: 5
      coreSize: 40
      maximumSize: 60
      allowMaximumSizeToDivergeFromCoreSize: true
    getCDAccountDetailsThreadPoolKey:
      maxQueueSize: 5
      coreSize: 40
      maximumSize: 60
      allowMaximumSizeToDivergeFromCoreSize: true
    submitCDRenewalThreadPoolKey:
      maxQueueSize: 5
      coreSize: 40
      maximumSize: 60
      allowMaximumSizeToDivergeFromCoreSize: true
    submitInternalFundTransferThreadPoolKey:
      maxQueueSize: 5
      coreSize: 40
      maximumSize: 60
      allowMaximumSizeToDivergeFromCoreSize: true
    getRetirementAccountDetailsThreadPoolKey:
      maxQueueSize: 5
      coreSize: 40
      maximumSize: 60
      allowMaximumSizeToDivergeFromCoreSize: true
    getAccountsThreadPoolKey:
      maxQueueSize: 5
      coreSize: 40
      maximumSize: 60
      allowMaximumSizeToDivergeFromCoreSize: true
  command:
    getRetirementAccountDetails:
      execution.isolation.thread.timeoutInMilliseconds: 10000
    submitCDRenewal:
      execution.isolation.thread.timeoutInMilliseconds: 10000
    submitInternalFundTransfer:
      execution.isolation.thread.timeoutInMilliseconds: 10000
    getCustomerInfo:
      execution.isolation.thread.timeoutInMilliseconds: 10000
    validateInternalFundTransfer:
      execution.isolation.thread.timeoutInMilliseconds: 10000
    getAccounts:
      execution.isolation.thread.timeoutInMilliseconds: 10000
    getCDRates:
      execution.isolation.thread.timeoutInMilliseconds: 10000
    getCDAccountDetails:
      execution.isolation.thread.timeoutInMilliseconds: 1
url-info-config:
  urlInfoMap:
    EXTERNAL_ACCOUNT_SERVICE:
      fullUrl: "http://sd-9ea5-6df7.nam.nsroot.net:8142/api/v1/aggregators/customers/{customerId}/accounts"
      serviceName: "B2B-AM-D-YodleeConnector"
      uri: "/api/v1/aggregators/customers/{customerId}/accounts"
      eurekaEnabled: true
    RATES_SERVICE:
      fullUrl: "http://sd-9ea5-6df7.nam.nsroot.net:8142/cdr/bank/rates/retrieve"
      serviceName: "NAM-CARDS-SIM-WRAP-APP-COMMON2"
      uri: "/6916/lisa/bank/rates/retrieve"
      eurekaEnabled: true
    CD_ACCOUNT_DETAILS_SERVICE:
      fullUrl: "http://sd-9ea5-6df7.nam.nsroot.net:8142/v1/domain/accounts/cdAccountDetails/retrieve"
      serviceName: "NAM-CARDS-SIM-WRAP-APP-COMMON2"
      uri: "/6916/lisa/v1/domain/accounts/cdAccountDetails/retrieve"
      eurekaEnabled: true
    ACCOUNT_PROFILE_REFRESH_SERVICE:
      fullUrl: "http://sd-9ea5-6df7.nam.nsroot.net:8142/cdr/private/v2/profiles/accounts/details"
      serviceName: "DGL-AM-V-ACCOUNTPROFILEWS-V2"
      uri: "/private/v1/accounts/profiles/refreshCache"
      eurekaEnabled: true
    ACCOUNT_PROFILE_SERVICE:
      fullUrl: "http://sd-9ea5-6df7.nam.nsroot.net:8142/cdr/private/v2/profiles/accounts/details"
      serviceName: "NAM-CARDS-SIM-WRAP-APP-COMMON2"
      uri: "/6916/lisa/private/v1/accounts/profiles"
      eurekaEnabled: true
    PROJECTED_CD_INFO_SERVICE:
      fullUrl: "http://sd-9ea5-6df7.nam.nsroot.net:8142/v1/domain/accounts/cdAccountProjectedInfo/retrieve"
      serviceName: "NAM-CARDS-SIM-WRAP-APP-COMMON2"
      uri: "/6916/lisa/v1/domain/accounts/cdAccountProjectedInfo/retrieve"
      eurekaEnabled: true
    INTERNAL_FUND_TRANSFER_VALIDATE_SERVICE:
      fullUrl: "http://sd-9ea5-6df7.nam.nsroot.net:8142/cdr/moneymovement/fundstransfer/validate"
      serviceName: "NAM-CARDS-SIM-WRAP-APP-COMMON2"
      uri: "/6916/lisa/moneymovement/fundstransfer/validate"
      eurekaEnabled: true
    SUBMIT_CD_RENEWAL:
      fullUrl: "http://sd-9ea5-6df7.nam.nsroot.net:8142/v1/domain/accounts/updateCDAccount"
      serviceName: "NAM-CARDS-SIM-WRAP-APP-COMMON2"
      uri: "/6916/lisa/v1/domain/accounts/updateCDAccount"
      eurekaEnabled: true
    CUSTOMER_DEMOGRAPHICS_SERVICE:
      fullUrl: "http://sd-9ea5-6df7.nam.nsroot.net:8142/cdr/private/v2/profiles/customers/retrieve"
      serviceName: "NAM-CARDS-SIM-WRAP-APP-COMMON2"
      uri: "/6916/lisa/private/v2/profiles/customers/retrieve"
      eurekaEnabled: true
    INTERNAL_FUND_TRANSFER_SUBMIT_SERVICE:
      fullUrl: "http://sd-9ea5-6df7.nam.nsroot.net:8142/cdr/moneymovement/fundstransfer/submit"
      serviceName: "NAM-CARDS-SIM-WRAP-APP-COMMON2"
      uri: "/6916/lisa/moneymovement/fundstransfer/submit"
      eurekaEnabled: true
    RETIREMENT_ACCOUNT_DETAILS_SERVICE:
      fullUrl: "http://sd-9ea5-6df7.nam.nsroot.net:8142/v1/retirement/accounts/details/retrieve"
      serviceName: "NAM-CARDS-SIM-WRAP-APP-COMMON2"
      uri: "/6916/lisa/api/private/v1/retirement/accounts/details/retrieve"
      eurekaEnabled: true
subApp:
  id: "DGL-SVC-V-AccountRenewalCD"
error-info-config:
  errorInfoMap:
    INTERNAL_SERVER_ERROR:
      httpStatus: 500
      errorCode: "INVALID_REQUEST"
      message: "internal server error"
      type: "ERROR"
    NOT_VALID_CD_ACCOUNT:
      httpStatus: 400
      errorCode: "INVALID_CD_ACCOUNT"
      message: "This is not a valid CD Account for Renewal"
      type: "ERROR"
    ST0064:
      httpStatus: 500
      errorCode: "REC_NOT_FOUND"
      message: "RATE REC NOT FOUND FOR"
      type: "ERROR"
    CD_MINIMUM_BALANCE_ERROR:
      httpStatus: 400
      errorCode: "CD_MINIMUM_BALANCE_ERROR"
      message: "Remaining CD balance cannot subceed the CD Minimum Balance."
      type: "ERROR"
    INSUFFICIENT_BALANCE:
      httpStatus: 500
      errorCode: "INSUFFICIENT_BALANCE"
      message: "Insufficient Balance in the Source Account."
      type: "ERROR"
    SP6032:
      httpStatus: 500
      errorCode: "HOLD_ON_ACCOUNT"
      message: "STOP/HOLD ON ACCOUNT"
      type: "ERROR"
    SP6033:
      httpStatus: 500
      errorCode: "NEW_ACCOUNT"
      message: "THIS IS A NEW ACCOUNT"
      type: "ERROR"
    CLOSE_CD_FLOW:
      httpStatus: 500
      errorCode: "CLOSE_CD_FLOW"
      message: "Partial withdrawal amounts must be less than CD account total."
      type: "ERROR"
    SP6014:
      httpStatus: 400
      contentId: "Landing.renewedCdError"
      errorCode: "CUSTOM_ALERT_ERROR"
      message: "Sorry, we can’t process this request.|Your CD renewal request has\
        \ previously been received and is being processed."
      type: "ERROR"
    VALIDATION_ERROR:
      httpStatus: 400
      errorCode: "INVALID_REQUEST"
      message: null
      type: "ERROR"
    TS9400:
      httpStatus: 400
      errorCode: "ACCOUNT_NOT_FOUND"
      message: "RECORD NOT FOUND"
      type: "ERROR"
    NOT_VALID_APP:
      httpStatus: 400
      errorCode: "CUSTOM_ALERT_ERROR"
      message: "Sorry, we can’t process this request on Mobile app at this time.|Please\
        \ retry on online.com."
      type: "ERROR"
    ST7600:
      httpStatus: 500
      errorCode: "CD_ACCT_NOT_FOR_RECIPIENT"
      message: "CD ACCOUNT NOT VALID FOR RECIPIENT"
      type: "ERROR"
    SP6018:
      httpStatus: 400
      contentId: "Landing.renewedCdError"
      errorCode: "CUSTOM_ALERT_ERROR"
      message: "Sorry, we can’t process this request.|Your CD renewal request has\
        \ previously been received and is being processed."
      type: "ERROR"
    ACCOUNT_ALREADY_UPDATED:
      httpStatus: 400
      contentId: "Landing.renewedCdError"
      errorCode: "CUSTOM_ALERT_ERROR"
      message: "Sorry, we can’t process this request.|Your CD renewal request has\
        \ previously been received and is being processed."
      type: "ERROR"
    ST0204:
      httpStatus: 500
      errorCode: "RENEWAL_BEEN_PROCESSED"
      message: "RENEWAL HAS ALREADY BEEN PROCESSED"
      type: "ERROR"
cdr-product-config:
  cdRenewalRetirementProducts:
  - 262
  - 268
  - 269
  cdRenewalProducts:
  - 184
  - 590
  - 591
tmx:
  applicationName:
    android: 154811
    browser: 144564
    ios: 168524

根据要求添加了 yaml 内容以及异常详细信息和代码提取。

任何帮助表示赞赏。

标签: javayaml

解决方案


正如您在此处此处看到的,此代码点对应于 windows-1252 中的右引号字符,可能是因为该文件是在 Windows 系统中编辑的。

如异常所示,iso-8859-1 或 utf-8 不支持此代码点:请参见例如此页面以比较每种编码如何支持此字符和其他字符。

要解决您的问题,只需编辑文件并将其保存为 iso-8859-1 或 utf-8 编码替换此字符,它应该可以工作。查看您的 YAML 文件很可能问题与can’t您的错误中的不同单词有关message


推荐阅读