无法从 IP 服务器检索 JSONArray 但我可以从普通服务器检索?

Posted

技术标签:

【中文标题】无法从 IP 服务器检索 JSONArray 但我可以从普通服务器检索?【英文标题】:Cant retrieve JSONArray from IP server but I can from normal server? 【发布时间】:2015-07-13 22:49:39 【问题描述】:

我正在将服务从普通域 DNS 服务器迁移到仅 IP 服务器,这为我的应用程序提供了 json 服务,问题是我无法在新 URL 中使用以下代码检索 JSONArray:

 protected JSONArray doInBackground(String... arg0) 
                String reponse;

                try
                    HttpClient httpclient = new DefaultHttpClient();
                    HttpPost httppost = new HttpPost(url);
                    HttpResponse responce = httpclient.execute(httppost);
                    HttpEntity httpEntity = responce.getEntity();
                    reponse = EntityUtils.toString(httpEntity);
                    return new JSONArray(reponse);
                    //With the oldURL I printed the JSON as a string and everithing OK but the new URL returns a null string of JSON
                catch(Exception e)
                    e.printStackTrace();

                


                return null;
            

String newurlexample = "http://111.22.333.44:1234/FOLD/blablabla";

String oldurl = "https:/example.com/FOLD/file.json";

我得到以下日志:

    07-13 17:47:02.142: W/System.err(18824): org.json.JSONException: Value Method of type java.lang.String cannot be converted to JSONArray
07-13 17:47:02.145: W/System.err(18824):    at org.json.JSON.typeMismatch(JSON.java:111)
07-13 17:47:02.145: W/System.err(18824):    at org.json.JSONArray.<init>(JSONArray.java:96)
07-13 17:47:02.146: W/System.err(18824):    at org.json.JSONArray.<init>(JSONArray.java:108)
07-13 17:47:02.146: W/System.err(18824):    at com.karlol.***.Doctor_Fragment$GetData.doInBackground(Doctor_Fragment.java:171)
07-13 17:47:02.146: W/System.err(18824):    at com.karlol.***.Doctor_Fragment$GetData.doInBackground(Doctor_Fragment.java:1)
07-13 17:47:02.147: W/System.err(18824):    at android.os.AsyncTask$2.call(AsyncTask.java:288)
07-13 17:47:02.147: W/System.err(18824):    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
07-13 17:47:02.147: W/System.err(18824):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
07-13 17:47:02.147: W/System.err(18824):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)

【问题讨论】:

我的第一反应是:你为什么不用Volley? 确保您可以访问您的 IP URL 并返回有效的 JSON。还打印“reponse”变量以查看服务器返回的内容 URL 返回一个有效的 JSON 并且“reponse”返回:Method[POST]Not Allowed, Please Make sure the REST MEthod [POST] for resource [my new address] is available in the other side! 您得到的实际输出是什么?添加响应的打印输出。因为这听起来像是您将字符串强制转换为 json 数组... 你是把 JSON 放到服务器还是从服务器检索 file.json?如果是后者,我想你会想要一个 GET 操作。您的 Web 服务器告诉您它不知道或不允许在 blahblah 位置进行 POST。无论哪种情况,请尝试将blahblah 替换为file.json 【参考方案1】:

从您问题的标题中,我可以注意到您使用的 URL 和新 ip 之间有问题..首先您需要确保您的新网络服务提供与旧网络服务相同的结果.. 您可以尝试使用以下任何方式检索数据:

try
       HttpClient httpclient = new DefaultHttpClient();
       HttpPost httppost = new HttpPost(url);
       HttpResponse responce = httpclient.execute(httppost);
       HttpEntity httpEntity = responce.getEntity();
       is = httpEntity.getContent();
       BufferedReader reader = new BufferedReader(new InputStreamReader(
            is));

      StringBuilder sb = new StringBuilder();
      String line = null;
      while ((line = reader.readLine()) != null) 
                sb.append(line + "\n");
            
            is.close();
        reponse = sb.toString();


       return new JSONArray(reponse);
       //With the oldURL I printed the JSON as a string and everithing OK but the new URL returns a null string of JSON

       catch(Exception e)
          e.printStackTrace();


编辑:

如果您使用共享主机服务器.. 在同一个 IP 上拥有多个网站并不罕见,仅通过站点名称来区分(所谓的虚拟主机)。您所做的仅适用于给定 IP 上有单个站点的情况。

编辑 2

您需要使用 RESTful 插件(chrome 或 firefox)测试您的网络服务,即Advanced rest client

【讨论】:

对不起,那个变量是什么类型的?输入流? static InputStream is = null; 您的网络服务不允许 POST 请求!你能给我一个你发送的例子吗?您需要使用 RESTful 插件测试您的网络服务 ... android端没有问题,需要验证restful服务..【参考方案2】:

在尝试使用它之前我们遇到了同样的问题。改变你的尝试并抓住这个。希望能帮助到你。

      FileCache filecache;


String result="";
                HttpURLConnection conn = null;
                String finalurl="http://111.22.333.44:1234/FOLD/blablabla";
                filecache = new FileCache(context);
                File f = filecache.getFile(finalurl);
                try 
                    URL url = new URL(finalurl);
                    conn = (HttpURLConnection) url.openConnection();
                    conn.setConnectTimeout(30000);
                    conn.setReadTimeout(30000);
                    conn.setInstanceFollowRedirects(true);
                    InputStream is = conn.getInputStream();
                    OutputStream os = new FileOutputStream(f);
                    Utils.CopyStream(is, os);
                    FileReader isr = new FileReader(f);
                    BufferedReader reader = new BufferedReader(isr);
                    StringBuilder sb = new StringBuilder();
                    String line = null;

                    while ((line = reader.readLine()) != null) 
                        sb.append(line + "\n");
                    
                    result = sb.toString();
                    is.close();
                    os.close();
                    conn.disconnect();
                    return new JSONArray(result);
                catch (Exception ex) 
                    Log.e("Error", ex+"can't access" + finalurl + result);
                

FileCache.java

import android.content.Context;
import java.io.File;

    /**
     * Created by cristiana214 on 1/26/2015.
     */
    public class FileCache 
        private File cacheDir;
        public FileCache(Context context) 
            // Find the dir to save cached images
            if (android.os.Environment.getExternalStorageState().equals(
                    android.os.Environment.MEDIA_MOUNTED)) 
                cacheDir = new File(context.getExternalCacheDir(),"folder/i");
             else
                cacheDir = context.getCacheDir();
            if (!cacheDir.exists())
                cacheDir.mkdirs();
        

        public File getFile(String url) 
            String filename = String.valueOf(url.hashCode());
            File f = new File(cacheDir, filename);
            return f;
        
        public void clear() 
            File[] files = cacheDir.listFiles();
            if (files == null)
                return;
            for (File f : files)
                f.delete();
        
    

Utils.java

import java.io.InputStream;
import java.io.OutputStream;

/**
 * Created by cristiana214 on 1/26/2015.
 */
public class Utils  
    public static void CopyStream(InputStream is, OutputStream os)
        final int buffer_size=1024*10;
        try
            byte[] bytes=new byte[buffer_size];
            for(;;)
                int count=is.read(bytes, 0, buffer_size);
                if(count==-1)
                    break;
                os.write(bytes, 0, count);
            
        
        catch(Exception ex)
    

【讨论】:

@Karlo A. López 如果您已经解决了问题,请发表评论。【参考方案3】:

根据你的错误代码

org.json.JSONException: Value Method of type java.lang.String cannot be converted to JSONArray

您正在尝试将字符串转换为 JSONArray。 还有一个指向 doInBackground 任务的指针,第 171 行,所以你一定要检查这一行。 我猜问题出在以下几行:

reponse = EntityUtils.toString(httpEntity);
return new JSONArray(reponse);

【讨论】:

【参考方案4】:

如果这对某人有帮助,我必须将请求更改为 GET 而不是 POST,并且这段代码运行良好,尽管我无法处理 POST 请求。

    try 
                    URL obj = new URL("http://anIPaddress/REST/Folder/Consult?Operation=AnOperation");
                    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
//con default method is GET
                    con.setRequestProperty("Accept", "application/json");
                    con.setRequestProperty("Content-Type", "application/json");
                    int responseCode = con.getResponseCode();
                    Log.v("Lolo", "\nSending 'GET' request to URL : " + con.getURL());
                    Log.v("Lolo", "RESPONSE CODE : " + responseCode);
                    BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
                    String inputLine;
                    StringBuffer response = new StringBuffer();
                    while ((inputLine = in.readLine()) != null) 
                        response.append(inputLine);
                    
                    in.close();

                    return new JSONArray(response.toString());
    

非常感谢您的回答和帮助。

【讨论】:

【参考方案5】:

在您的日志消息中检查这一行:

W/System.err(18824): org.json.JSONException: java.lang.String 类型的值方法无法转换为 JSONArray

您收到此异常是因为您收到的来自服务器的响应未格式化为 JSON 格式。因此,当您尝试将响应字符串转换为 JSONArray 时,它会抛出上述 JSONException。

现在您的问题的解决方案是:您需要确保响应格式正确为 JSON 格式。并在解析为 JSON 之前记录您的响应,您可以通过它检查响应是否正确。

希望这对你有帮助:) 谢谢

【讨论】:

信息不是 JSON 格式,因为它没有收到任何信息!问题出在请求上。

以上是关于无法从 IP 服务器检索 JSONArray 但我可以从普通服务器检索?的主要内容,如果未能解决你的问题,请参考以下文章

JSONArray 无法根据 indexPath 获取数组

Swift 3 - 无法弄清楚如何从 jsonArray 创建 json 对象

无法使用改造解析对象内部 jsonarray 的 jsonarray?

jsonArray请求没有响应[关闭]

从 JSONArray 转换为 String 然后再转换回来

如何修复 JSONObject 无法转换为 JSONArray