最近需要对用户输入的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); // \r escCodes.put(10, 110); // \n String str = "fuck\r\nlala"; char[] cs = str.toCharArray(); for (char c : cs) { int charCode = (int) c; if (charCode < 24 && escCodes.containsKey(charCode)) { // need escape sb.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)