需求背景:
SAP需要将单据信息生成文件,通过SFTP的方式放在服务器上,同时需要解析对方系统生成的文件,在SAP端进行单据处理,其中会涉及到编码问题,SAP PI默认是以UTF-8编码去解析以及生成文件的,而目标文件是Shift_JIS编码的,读取的时候一方面存在乱码问题,一方面存在需要按字节长度去解析的问题,生成的时候也是如此,需要按字节长度生成,同时生成的文件编码也需要为Shift_JIS。
正解如下:
接收方:
fieldFixedLengths用于指定拆分字段长度。
fieldFixedLengthType用于指定长度类型。
关于Separators的一些参数,换行符需要使用'nl'来指定。
同时需要在高级参数中添加encodingScheme参数,使用该参数指定了编码方案,fieldFixedLengthType=byte才会生效,同时也会以指定的编码生成文件,否则将会以字符长度去转换,并且以UTF-8编码生成文件(非UTF-8编码的文字内容就会是乱码)。
发送方:
在高级参数中添加encodingFormat来指定源文件编码格式,同时fieldFixedLengthType=byte才会正常生效,否则解析是按照字符长度去解析的,并且解析出来的文字内容会是乱码(如果源文件内容是非UTF-8编码时),因为PI默认是以UTF-8去解析及生成文件的。
走弯路的字节问题解决办法:
IR中的配置:
在Message Mapping中的Function页签,创建自定义方法(User Define Function):
源码如下,核心方法就是通过字符串对应的字符范围来判定是全角字符还是半角字符:
//Fill the byte length with the return length
ImportString = ImportString.format("%-" + TotalLength + "s", ImportString);
//Return String
String retStr = "";
//String length
int length = ImportString.length();
//Get String Array List
char[] arr = ImportString.toCharArray();
//Initial Length
int length_character = 0;
//Check the number of bytes per character
for(int i = 0;i<length;i++) {
//'\u0020'~'\u007E' and '\uFF61'~'\uFF9F' is Half corner character
if((arr[i]>='\u0020' && arr[i]<='\u007E') || (arr[i]>='\uFF61' && arr[i]<='\uFF9F')) {
length_character = length_character + 1;
}else {
length_character = length_character + 2;
}
//If the cumulative length same with Return length, returned
if(length_character == TotalLength) {
retStr = retStr + String.valueOf(arr[i]);
break;
}else {
//If the cumulative length is greater than the return length, one byte is still needed eg:5 > 4
if(length_character > TotalLength) {
retStr = retStr + " ";
break;
}else {
retStr = retStr + String.valueOf(arr[i]);
}
}
}
return retStr;
然后为每一个字段做mapping映射,通过一个常量字符串指定字节长度,经过ConvertString方法后,即可得到处理后的字符串,超过长度的截取掉,不足的则以空格补充长度,经过映射之后,在ID中再进行简单的配置即可完成。
ID中的配置:
因为IR中通过UDF将每个字段已经转换为正确的长度,所以此处直接按照字段进行拆分即可达到效果。
走弯路的编码问题解决办法:
接收方:
模块处理函数:TextCodepageConversionBean,使用方法如下:
在Module页签中添加模块名称:AF_Modules/TextCodepageConversionBean,类型为Local Enterprise Bean,在Module Configuration中添加参数Conversion.charset,值为目标编码。
Tips:注意参数名是大小写敏感的。
以上。