本来就是简简单单的一个java发送http get请求,有两种方式。
第一种用URLConnection:
public static String get(String url) throws IOException { BufferedReader in = null; URL realUrl = new URL(url); // 打开和URL之间的连接 URLConnection connection = realUrl.openConnection(); // 设置通用的请求属性 connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("connection", "Keep-Alive"); connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); connection.setConnectTimeout(5000); connection.setReadTimeout(5000); // 建立实际的连接 connection.connect(); // 定义 BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader(connection.getInputStream())); StringBuffer sb = new StringBuffer(); String line; while ((line = in.readLine()) != null) { sb.append(line); } in.close(); return sb.toString(); }
第二种用java HTTP客户端:HttpGet、HttpClient、HttpResponse等
public static String httpGet(String url, String charset) throws HttpException, IOException { String json = null; HttpGet httpGet = new HttpGet(); // 设置参数 try { httpGet.setURI(new URI(url)); } catch (URISyntaxException e) { throw new HttpException("请求url格式错误。"+e.getMessage()); } // 发送请求 HttpClient client=HttpClients.createDefault(); HttpResponse httpResponse = client.execute(httpGet); // 获取返回的数据 HttpEntity entity = httpResponse.getEntity(); byte[] body = EntityUtils.toByteArray(entity); StatusLine sL = httpResponse.getStatusLine(); int statusCode = sL.getStatusCode(); if (statusCode == 200) { json = new String(body, charset); entity.consumeContent(); } else { throw new HttpException("statusCode="+statusCode); } return json; }
实现类如下:
package com.tpot.DataDownload; import org.apache.http.HttpEntity; import org.apache.http.HttpException; import org.apache.http.HttpResponse; import org.apache.http.StatusLine; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import sun.security.krb5.Config; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URISyntaxException; import java.net.URL; import java.net.URI; import java.net.URLConnection; public class Downloader { public static String httpGet(String url, String charset) throws HttpException, IOException { String json = null; HttpGet httpGet = new HttpGet(); // 设置参数 try { httpGet.setURI(new URI(url)); } catch (URISyntaxException e) { throw new HttpException("请求url格式错误。"+e.getMessage()); } // 发送请求 HttpClient client=HttpClients.createDefault(); HttpResponse httpResponse = client.execute(httpGet); // 获取返回的数据 HttpEntity entity = httpResponse.getEntity(); byte[] body = EntityUtils.toByteArray(entity); StatusLine sL = httpResponse.getStatusLine(); int statusCode = sL.getStatusCode(); if (statusCode == 200) { json = new String(body, charset); entity.consumeContent(); } else { throw new HttpException("statusCode="+statusCode); } return json; } public static String get(String url) throws IOException { BufferedReader in = null; URL realUrl = new URL(url); // 打开和URL之间的连接 URLConnection connection = realUrl.openConnection(); // 设置通用的请求属性 connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("connection", "Keep-Alive"); connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); connection.setConnectTimeout(5000); connection.setReadTimeout(5000); // 建立实际的连接 connection.connect(); // 定义 BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader(connection.getInputStream())); StringBuffer sb = new StringBuffer(); String line; while ((line = in.readLine()) != null) { sb.append(line); } in.close(); return sb.toString(); } public static void main(String[] args) throws IOException, HttpException { // Configer.configProxy(); System.out.println(get("http://www.baidu.com")); // System.out.println(httpGet("http://px.hnsgkb.com/","utf-8")); } }
然而编译运行,却发现报错permission denied:
一开始以为是环境变量的原因:https://blog.csdn.net/jiangshubian/article/details/76549073 添加了环境变量之后还是不行
然后以为是windows防火墙的原因,先将idea添加到了防火墙允许列表中,不行;然后干脆关闭防火墙,还是不行。
网上说也可能是代理的原因,如果使用代理的话可以按如下编写一个设置代理的函数configProxy,然后在发送请求前调用一下这个函数就行了:
package com.tpot.DataDownload; import java.util.Properties; public class Configer { public static void configProxy(){ Properties prop=System.getProperties(); prop.setProperty("proxySet","true"); prop.setProperty("http.proxyHost","proxy.xxxx.com"); prop.setProperty("http.proxyPort","8080"); prop.setProperty("http.proxyUser","xxxxx"); prop.setProperty("http.proxyPassword","xxxxx"); prop.setProperty("https.proxyHost","proxy.xxxxx.com"); prop.setProperty("https.proxyPort","8080"); prop.setProperty("https.proxyUser","xxxxx"); prop.setProperty("https.proxyPassword","xxxxx"); } }
但是我并没有使用任何代理啊,应该不是这个的问题,果然试着配了一下,还是不行。
那么为什么呢,我把我的代码给别人考了一份,然后在别人的机器上跑,结果跑通了!
最后发现是因为我的电脑是通过手机USB共享网络连的网,很可能是手机端有权限控制!
我的猜想是,之前看过一篇文章,说安卓中java如果要发送http请求 ,必须在manifest.xml中配置一个东西,否则安装存在权限控制:https://blog.csdn.net/shenyuemei/article/details/8003654
我猜就是因为这个,电脑通过手机联网,所以请求在经过android系统时,被android拦截!
暂时没找到更好的解决办法,所以如果想用java发送http请求的话就不要用android手机共享网络的方式上网了。。。
很好奇如果用ios给电脑共享网络,会不会存在同样的问题,下次测试一下。。
整整一个下午都在搞这,辣鸡安卓,毁我青春