最近需要对用户输入的CRLF即(\r\n)做escape,参考了一下jackson的处理方式,大概就是把字符串转换成char数组,循环判断每个字符的ascii编码是否等于需要做escape。code如下:
String str = "fuck\r\nlala";char[] cs = str.toCharArray();for (char c : cs) {if ((int) c == 13) {System.out.println('\\');System.out.println((char) 114);} else if ((int) c == 10) {System.out.println('\\');System.out.println((char) 110);} else {System.out.println(c);}}
重构之后的代码
StringBuilder sb = new StringBuilder();HashMap<Integer, Integer> escCodes = new HashMap<Integer, Integer>();escCodes.put(13, 114); // \rescCodes.put(10, 110); // \nString str = "fuck\r\nlala";char[] cs = str.toCharArray();for (char c : cs) {int charCode = (int) c;if (charCode < 24 && escCodes.containsKey(charCode)) { // need escapesb.append('\\');int escCode = escCodes.get(charCode);sb.append((char) escCode);}else{sb.append(c); }}System.out.println(sb.toString());
jackson的测试代码
ObjectMapper mapper = new ObjectMapper();Map param = new HashMap();String str = "中文fuck\r\nlala";param.put("test", str);String value = mapper.writeValueAsString(param);System.out.println(value);
jackson的调用堆栈:
- StdSerializerProvider.serializeValue()
- StdSerializerProvider._serializeValue()
- MapSerializer.serialize(Map value,JsonGenerator jgen, SerializerProvider provider)
- MapSerializer.serializeFields(Map value,JsonGenerator jgen, SerializerProvider provider)
- JsonGenerator.writeString(String text)
- WriterBasedGenerator._writeString(String text)
- WriterBasedGenerator._writeString2(final int len)