JSON

服务器端json数据文件分割合并简介(2)

字号+ 作者:H5之家 来源:H5之家 2017-09-03 18:01 我要评论( )

为啥非要单独传入一个绝对路径呢?其实可以直接传入Json文件的路径,这样既能拿到需要解析的Json字符串,又能获取当前Json文件的绝对路径。但这样有一个缺点,就是每调用一次,就要读一次文件,小菜单独把路径写成一

  为啥非要单独传入一个绝对路径呢?其实可以直接传入Json文件的路径,这样既能拿到需要解析的Json字符串,又能获取当前Json文件的绝对路径。但这样有一个缺点,就是每调用一次,就要读一次文件,小菜单独把路径写成一个参数,就是要把读文件的过程留给用户,具体怎么读,由用户说了算,最终把需要解析的Json字符串和参照路径给我就可以了。例如:

  1 String json = "{@Jean(\"item1\",\"./../../item.js\"),@Jean(\"item2\",\"../item.js\")}";

  2 System.out.println(parseAll(json, "E:/root/json")); //print {"item1": {"name": "xxx1"},"item2": {"name": "xxx2"}}

  第二个方法可以直接解析一个@Jean表达式,不多解释。例如:

  1 String expression = "@Jean(\"item1\",\"./../../item.js\")";

  2 System.out.println(parseOne(expression, "E:/root/json")); //print "item1": {"name": "xxx1"}

  第三个方法可以解析指定的@Jean表达式,@Jean表达式第一个参数是属性名称,想解析哪个属性,就把它放在List中,其他不做解析的,属性值为null。这样就实现了懒加载。例如:

  1 List names = new ArrayList();

  2 names.add("item1");

  3 String json = "{@Jean(\"item1\",\"./../../item.js\"),@Jean(\"item2\",\"../item.js\")}";

  4 System.out.println(parseTarget(json, "E:/root/json", names)); //print {"item1": {"name": "xxx"},"item2": null}

  Jean源码

  1 import java.io.BufferedReader;

  2 import java.io.File;

  3 import java.io.FileInputStream;

  4 import java.io.IOException;

  5 import java.io.InputStreamReader;

  6 import java.util.ArrayList;

  7 import java.util.HashMap;

  8 import java.util.List;

  9 import java.util.Map;

  10 import java.util.regex.Matcher;

  11 import java.util.regex.Pattern;

  12

  13

  14 /**

  15 * json文件合并工具类

  16 * @author 杨元

  17 */

  18 public class Jean {

  19

  20 /**

  21 * 识别jean表达式

  22 */

  23 private static Pattern jeanRegex = Pattern.compile("(@Jean\\((\"[^\"]*\",)?\"[^\"]*\"\\))");

  24 /**

  25 * 识别jean表达式中的所有参数

  26 */

  27 private static Pattern paramRegex = Pattern.compile("\"([^\"]*)\"");

  28 /**

  29 * 识别jean表达式中的name参数

  30 */

  31 private static Pattern nameRegex = Pattern.compile("\"([^\"]*)\",");

  32 /**

  33 * 默认属性名称

  34 */

  35 private static String defaultName = "jean";

  36

  37 /**

  38 * 解析所有的jean表达式

  39 * @param json json字符串

  40 * @param jsonPath json字符串所在路径,完整路径

  41 * @return 解析后的json字符串

  42 */

  43 public static String parseAll(String json,String jsonPath){

  44 //识别jean表达式

  45 List jeans = regexMatchList(jeanRegex, json);

  46 jeans = noRepeat(jeans);

  47

  48 //解析

  49 for(String jean : jeans){

  50 json = json.replace(jean, parse(jean, jsonPath));

  51 }

  52

  53 return json;

  54 }

  55

  56 /**

  57 * 解析单个jean表达式

  58 * @param express jean表达式

  59 * @param jsonPath json字符串所在路径,完整路径

  60 * @return 解析结果

  61 */

  62 public static String parseOne(String express,String jsonPath){

  63 return parse(express, jsonPath);

  64 }

  65

  66 /**

  67 * 解析特定的jean表达式

  68 * @param json json字符串

  69 * @param jsonPath json字符串所在路径,完整路径

  70 * @param names 需要解析的属性名称列表

  71 * @return 解析后的json字符串

  72 */

  73 public static String parseTarget(String json,String jsonPath,List names){

  74 //识别jean表达式

  75 List jeans = regexMatchList(jeanRegex, json);

  76 jeans = noRepeat(jeans);

  77 //处理属性名映射

  78 Map

  79 for(String s : names){

  80 nameMap.put(s, true);

  81 }

  82

  83 //解析

  84 String replacement = "";

  85 Matcher matcher = null;

  86 String name = "";

  87 for(String jean : jeans){

  88 matcher = nameRegex.matcher(jean);

  89

  90 //判断是否传入属性名称

  91 if(matcher.find()){

  92 name = matcher.group(1);

  93 //判断是否需要解析

  94 if(nameMap.get(name) != null){

  95 replacement = parse(jean, jsonPath);

  96 }else{

  97 //不需要解析直接将属性值写为null

  98 replacement = "\""+name+"\": null";

  99 }

  100 }else{

  101 //无属性名直接用默认的jean

  102 replacement = "\""+defaultName+"\": null";

  103 }

  104

  105 json = json.replace(jean, replacement);

  106 }

  107

  108 return json;

  109 }

  110

  111 /**

  112 * 解析jean表达式

  113 * @param express jean表达式

  114 * @param jsonPath json文件所在路径,完整路径

  115 * @return jean表达式执行结果

  116 */

  117 private static String parse(String express,String jsonPath){

  118 //识别参数

  119 List params = regexMatchList(paramRegex, express);

  120 //默认属性名称

  121 String name = defaultName;

  122 //格式化路径

  123 jsonPath = removeSuffix(jsonPath, "/");

  124

  125 //判断是否传入了属性名称

  126 if(params.size() > 1){

  127 name = params.get(0);

  128 }

  129

  130 //解析路径

  131 String path = getAbsolutePath(jsonPath, params.get(params.size()-1));

  132

  133 //读取内容并返回

  134 name = wrapWith(name, "\"");

  135 return name + ": " + readJsonFile(path);

  136 }

  137

  138 /**

  139 * 从字符串中移除指定后缀

  140 * @param source 源字符串

  141 * @param suffix 需要移除的后缀

  142 * @return 处理后的源字符串

  143 */

  144 private static String removeSuffix(String source,String suffix){

  145 if(source.endsWith(suffix)){

  146 source = source.substring(0, source.length()-suffix.length());

  147 }

  148

  149 return source;

  150 }

  151

  152 /**

  153 * list内容去重

  154 * @param list 内容为string的list

  155 * @return 内容去重后的list

  156 */

  157 private static List noRepeat(List list){

  158 Map

  159 List result = new ArrayList();

  160

  161 for(String s : list){

  162 map.put(s, null);

  163 }

  164

  165 for(String s : map.keySet()){

  166 result.add(s);

  167 }

  168

  169 return result;

  170 }

  171

  172 /**

  173 * 用指定的字符串包裹内容

  174 * @param content 内容

  175 * @param wrap 包裹字符串

  176 * @return 包裹后的内容

  177 */

  178 private static String wrapWith(String content,String wrap){

  179 return wrap+content+wrap;

  180 }

  181

  182 /**

  183 * 读取Json文件(纯文本文件,utf-8编码)

  184 * 这个方法可以替换成自己项目中封装的方法

  185 * @param path 文件路径

  186 * @return 文件内容

  187 */

  188 private static String readJsonFile(String path){

  189 String encoding = "utf-8";

  190 StringBuilder sb = new StringBuilder(256);

  191

  192 File file = new File(path);

  193 InputStreamReader iReader = null;

  194 BufferedReader bReader = null;

  195

  196 try{

  197 iReader = new InputStreamReader(new FileInputStream(file), encoding);

  198 bReader = new BufferedReader(iReader);

  199 String line = null;

  200

  201 while((line = bReader.readLine()) != null){

  202 sb.append(line.trim());

  203 }

  204

  205 bReader.close();

  206 iReader.close();

  207

  208 }catch(Exception e){

  209 if(iReader != null){

  210 try {

  211 iReader.close();

  212 } catch (IOException e1) {

  213 iReader = null;

  214 }

  215 }

  216 , if(bReader != null){

  217 try {

  218 bReader.close();

  219 } catch (IOException e1) {

  220 bReader = null;

  221 }

  222 }

  223 }

  224

  225 return sb.toString();

  226 }

  227

  228 /**

  229 * 将相对路径转换成绝对路径

  230 * 只识别 ./ ../

  231 * @param refrence 基准参照路径

  232 * @param relative 相对路径表达式

  233 * @return 绝对路径

  234 */

  235 private static String getAbsolutePath(String refrence,String relative){

  236 if(relative.startsWith("./")){

  237 refrence = getAbsolutePath(refrence, relative.replaceFirst("\\./", ""));

  238 }else if(relative.startsWith("../")){

  239 refrence = getAbsolutePath(refrence.substring(0, refrence.lastIndexOf("/")),

  240 relative.replaceFirst("\\.\\./", ""));

  241 }else{

  242 refrence = refrence + "/" + relative;

  243 }

  244

  245 return refrence;

  246 }

  247

  248 /**

  249 * 将正则表达式的匹配结果转换成列表

  250 * @param regex 正则表达式对象

  251 * @param input 要检索的字符串

  252 * @return 结果列表

  253 */

  254 private static List regexMatchList(Pattern regex,String input){

  255 List result = new ArrayList();

  256 Matcher matcher = regex.matcher(input);

  257 while(matcher.find()){

  258 result.add(matcher.group(1));

  259 }

  260

  261 return result;

  262 }

  263

  264

  265 }

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • java将数据转成json编码格式技术实例教程

    java将数据转成json编码格式技术实例教程

    2017-09-03 16:01

  • Core Json–JSON和Java

    Core Json–JSON和Java

    2017-09-03 16:00

  • PHP实现json_encode函数不转义中文的多种方法

    PHP实现json_encode函数不转义中文的多种方法

    2017-09-02 16:03

  • C#对象转Json序列化

    C#对象转Json序列化

    2017-09-02 12:00

网友点评