【问题标题】:JavaScript array to javaJavaScript数组到java
【发布时间】:2014-09-06 20:59:44
【问题描述】:

我有一个 javascript 数组,表示我所有学校 https://dl.dropboxusercontent.com/u/16258361/urnik/data.js 的时间表。我正在编写一个 android 应用程序,我需要下载数据并以某种方式将其解析为 java 数组。我什至可以使用 php 或其他 Web 服务来下载数据并将其生成 json/xml 或类似的东西。但到目前为止我找不到任何好的解决方案,所以我想请教您的任何想法。

谢谢:)

【问题讨论】:

  • 一开始为什么会有这样的 JS 数组呢?它看起来很糟糕。请改用 JSON。
  • 是的,我知道,但这就是我所拥有的。这个网络应用程序实际上使用它来安排dl.dropboxusercontent.com/u/16258361/urnik/urnik.html。这是唯一可用的数据:/
  • 你试过 ScriptEngine 了吗?
  • 好吧,这似乎是一个很好的解决方案。让我完成它,然后我将发布一个描述它的答案。知道我的同学在目标 c 中为 iOS 编写相同的应用程序如何解决这个问题吗?

标签: java javascript php android json


【解决方案1】:

这应该可行。

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;

public class Main {
   public static void main(String[] args) throws Exception {
      String html = "";


      URL url = new URL("https://dl.dropboxusercontent.com/u/16258361/urnik/data.js");
      URLConnection connection = url.openConnection();
      BufferedReader in = new BufferedReader(new InputStreamReader(
           connection.getInputStream()));
      String inputLine;
      while ((inputLine = in.readLine()) != null)
         html += inputLine;
      in.close();


      String array[] = html.split("podatki");
      ArrayList<String> dataArray = new ArrayList<String>();
      for (int i = 2; i < array.length; i++)
         dataArray.add(array[i]);

      String last = dataArray.get(dataArray.size()-1);
      String lastCleared = "";
      for (int i = 0; i < last.length(); i++) {
         if (!last.substring(i, i+1).contains("r")) lastCleared += last.substring(i, i+1);
         else break;
      }
      dataArray.set(dataArray.size() - 1, lastCleared);

      for (int i = 0; i < dataArray.size(); i++) {
         String string = dataArray.get(i);
         if (string.contains("new Array")) {
            dataArray.remove(i);
            i--;
         }
         else {
            string = string.replaceAll("]\\[", ";");
            string = string.replaceAll("\\[", "");
            string = string.replaceAll("]", "");
            string = string.replaceAll("\"", "");
            string = string.replace(" = ", ";");
            dataArray.set(i, string);
        }
      }

      int lastIndex1;
      String string = "";
      String lastString = dataArray.get(dataArray.size() - 1);
      for (int i = 0; i < lastString.length(); i++) {
         if (lastString.substring(i, i+1).contains(";"))
            break;
         string += lastString.substring(i, i+1);
      }

      lastIndex1 = Integer.parseInt(string);
      boolean start = false;
      for (int i = 0; i < lastString.length(); i++) {
         if (start) {
            string = lastString.substring(i, i + 1);
            break;
      }
      if (lastString.substring(i, i+1).contains(";"))
           start = true;
      }
      int lastIndex2 = Integer.parseInt(string);

      String finalData[][] = new String[lastIndex1+1][lastIndex2+1];
      for (int i = 0; i < dataArray.size(); i++) {
         String components[] = dataArray.get(i).split(";");
         if (components.length == 3)
            finalData[Integer.parseInt(components[0])][Integer.parseInt(components[1])] = components[2];
         else
           finalData[Integer.parseInt(components[0])][Integer.parseInt(components[1])] = "";           
      }

      for (int i = 0; i < finalData.length; i++) {
         for (int j = 0; j < finalData[i].length; j++)
            System.out.println(finalData[i][j]);
         System.out.println("\n");
      }
   }
}

【讨论】:

  • 感谢 DzinVision,完美运行。虽然执行需要几秒钟,但它似乎是最好的解决方案。 :)
【解决方案2】:

好吧,我终于明白了,所以我正在回答我自己的问题。

Ntsh 使用 ScriptEngine(参见问题的 cmets)的想法很好,并且在 java 中运行良好,但由于默认情况下它不是 android 的一部分,所以我不得不导入 jar。即使代码可以编译,它似乎也无法在某些设备上运行(我让它只在我的 4.2 Genymotion VM 中运行)。

所以我搜索了另一种方法并决定使用 webview 来运行 javascrip。这似乎是一个糟糕的解决方案,但它确实有效:

首先我在服务器上创建了一个 php 文件,它采用 js file,在其周围添加了一些 html 和 javascript 代码,使其成为有效的 html 并从这个 js 数组中生成 json 并打印出来。

在 android 上,我只是在隐藏的 webview 中打开这个 url,一旦页面加载,我会获取它的源并提取相关数据,将其从 json 解析为 java。 This post 对此非常有帮助。

但是,这种方法有一些缺点:

  • 它不能在后台运行(例如使用后台服务和广播接收器),因为 webview 是一个 gui 元素
  • 它具有安全性,因为任何加载到 webview 的 js 文件都可以随时调用该函数(现在仅在加载页面时调用)。这就是它可以注入一些其他文本等的方式......

所以如果有人有更好的解决方案,请告诉我。

【讨论】:

  • 对于 android 的 selenium 怎么样? Selenium 是一个无头浏览器,可以像脚本引擎那样执行 js,但希望它能适用于你需要的版本。
  • 或者您可以将其解析为普通文本,然后手动构建您的 java 数组。如果您对数据的格式有信心。
  • 这就是我目前正在做的事情。它会起作用,但它是一个难看的意大利面条代码:D
  • 至少它会起作用:P。检查硒。我没用过,但它可能是你需要的。
  • @Žiga Patačko Koderman 我可能有另一种方法。假设数据将具有相似且统一的结构,您可以使用正则表达式来获取所有值。像这样:rubular.com/r/sZwfeBusqh ... 正如您在匹配组部分中看到的,正则表达式将返回值数组。拆分数组应该很简单。不知道需要多少时间。让我们知道这种方法是否有效。
【解决方案3】:

关于iOS部分,我找到了这个http://hayageek.com/execute-javascript-in-ios/

import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

import sun.org.mozilla.javascript.internal.NativeArray;

public class Main {

    public static void main(String[] args) {
        try {

            URL jsUrl = new URL("https://dl.dropboxusercontent.com/u/16258361/urnik/data.js");
            Reader reader = new InputStreamReader(jsUrl.openStream());
            ScriptEngineManager manager = new ScriptEngineManager();
            ScriptEngine engine = manager.getEngineByName("JavaScript");

            // evaluate script
            engine.eval(reader);
            System.out.println(Arrays.toString(parseJsArray(engine, "podatki").toArray()));
            System.out.println(Arrays.toString(parseJsArray(engine, "razredi").toArray()));
            System.out.println(Arrays.toString(parseJsArray(engine, "ucitelji").toArray()));
            System.out.println(Arrays.toString(parseJsArray(engine, "ucilnice").toArray()));            

        } catch (Exception e) {
            e.printStackTrace();
        }    
    }

    public static List<Object> parseJsArray(ScriptEngine engine, String key) {
        NativeArray jsVar = (NativeArray)engine.get(key);
        List<Object> list = new ArrayList<Object>((int)jsVar.getLength());
        for(int i = 0; i < jsVar.getLength(); i++) {
            if(jsVar.get(i).getClass().equals(NativeArray.class)) {
                NativeArray inner = (NativeArray)jsVar.get(i);
                List<Object> innerList = new ArrayList<Object>((int)inner.getLength());
                for(int j = 0; j < inner.getLength(); j++) {
                    innerList.add(inner.get(j));
                }
                list.add(innerList);
            } else {
                list.add(jsVar.get(i));
            }
        }
        return list;
    }
}

【讨论】:

  • 很好,我编写了类似的代码,并且在 java 中完美运行,但我无法将它导入到 android 项目中。所以知道怎么做,因为导入 jar 似乎不起作用(见我的回答)?
猜你喜欢
  • 2018-11-26
  • 1970-01-01
  • 2015-10-15
  • 1970-01-01
  • 1970-01-01
  • 2014-05-01
  • 2016-05-04
  • 1970-01-01
  • 2010-10-05
相关资源
最近更新 更多