// 文件路径 D:\ApacheServer\web_java\HelloWorld\src\com\test\TestHttpCurl.java package com.test; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.Map; import java.util.List; // PHP 作为接受请求端服务器 public class TestHttpCurl { public void testfun() { // 请求网址,需要加上 http:// 前缀来指明协议 String urlStr = "http://localhost/test/t1.php"; // "https://www.baidu.com"; HttpURLConnection httpURLConnection = null; InputStream inputStream = null; BufferedReader bufferedReader = null; // 连接方式:GET 或者 POST String requestMethod = "POST"; // POST 请求参数类别,此变量为自定义控制区分传参类别,param(单传参), json(参数为json串), file(上传文件),param_file(传参并上传文件) String postType = "param_file"; // 此变量自定义控制将响应信息转为文本输出还是文件保存起来,str(将响应信息直接打印),file(将响应信息保存为文件) String ResponseType = "str"; // 存放数据 StringBuffer stringBuffer = null; // 返回结果字符串 String str_result = null; try { // 创建远程url连接对象 URL url = new URL(urlStr); // 通过远程url连接对象打开一个连接,强转成httpURLConnection类 httpURLConnection = (HttpURLConnection) url.openConnection(); // 设置连接主机服务器的超时时间:15000毫秒 httpURLConnection.setConnectTimeout(15000); // 设置读取远程返回的数据时间:60000毫秒 httpURLConnection.setReadTimeout(60000); // 设置请求报头消息 // 维持长连 //httpURLConnection.setRequestProperty("Connection", "Keep-Alive"); // 设置编码 //httpURLConnection.setRequestProperty("Charset", "UTF-8"); // 自定义报头信息,PHP 端可以用 $_SERVER ['HTTP_TESTHEADER'] 获取 //httpURLConnection.setRequestProperty("testHeader", "testHeaderVal"); // 允许读入,默认值为 true,之后就可以使用httpURLConnection.getInputStream().read(); 因为总是使用 httpURLConnection.getInputStream() 获取服务端的响应,因此默认值是 true //httpURLConnection.setDoInput(true); // 设置连接方式:GET/POST,默认是GET httpURLConnection.setRequestMethod(requestMethod); if(requestMethod == "POST") { // 允许写出, 默认值为 false,之后就可以使用httpURLConnection.getOutputStream().write(); POST请求,参数要放在 http 正文内,因此需要设为 true,默认情况下是 false httpURLConnection.setDoOutput(true); // POST 请求不能使用缓存 httpURLConnection.setUseCaches(false); // 要上传的文件,需上传文件时用到,在项目基础路径下的 upload 文件夹内 String fileName = "00125943U-0.jpg"; // 项目基础路径 String appBase = Thread.currentThread().getContextClassLoader().getResource("../../").toString().substring(6); // 获取文件的完整绝对路径,File.separator 表示目录分割斜杠,这里完整绝对路径为 这里完整路径为 D:/ApacheServer/web_java/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/HelloWorld/upload/00125943U-0.jpg String fullFileName = appBase + "upload" + File.separator + fileName; // 创建要上传的 file 对象 File uploadFile = new File(fullFileName); // 设置请求参数内容 // POST 方式传递参数的本质是:从连接中得到一个输出流,通过输出流把数据写到服务器,所以以下所有 POST 传参语句内容,除了设置报头语句,均可在 httpURLConnection.connect(); 语句之后执行 String body = ""; if(postType == "param") { // PHP 通过 $_POST['testKey1']; $_POST['testKey2']; 获取请求参数 // 数据的拼接采用键值对格式,键与值之间用=连接。每个键值对之间用&连接 body = "testKey1=testVal1&testKey2=testVal2"; BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(httpURLConnection.getOutputStream(), "UTF-8")); bufferedWriter.write(body); bufferedWriter.close(); }else if(postType == "json") { // PHP 通过 file_get_contents('php://input'); 获取上传的 json 串 // 设置 POST 报头数据类型是 json 格式 httpURLConnection.setRequestProperty("Content-Type", "application/json;charset=utf-8"); // 拼接标准 json 字符串 body = "{\"testKey1\":\"testVal1\",\"testKey2\":\"testVal2\"}"; BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(httpURLConnection.getOutputStream(), "UTF-8")); bufferedWriter.write(body); bufferedWriter.close(); }else if(postType == "file") { // PHP 通过 $file_str = file_get_contents('php://input'); 获取上传图片内容,然后通过 file_put_contents('test.jpg',$file_str); 将图片保存在 PHP 服务器本地 // 设置 POST 报头数据类型是 file 格式 httpURLConnection.setRequestProperty("Content-Type", "file/*"); // 用连接创建一个输出流 OutputStream outputStream = httpURLConnection.getOutputStream(); // 把文件封装成一个流 FileInputStream fileInputStream = new FileInputStream(uploadFile); // 每次从输入流实际读取到的字节数 int len = 0; // 定义一个字节数组,相当于缓存,数组长度为1024,即缓存大小为1024个字节 byte[] cache = new byte[1024]; // inputStream.read(cache)) 方法,从输入流中读取最多 cache 数组大小的字节,并将其存储在 cache 中。以整数形式返回实际读取的字节数,当文件读完时返回-1 while((len = fileInputStream.read(cache)) != -1){ // 每次把数组 cache 从 0 到 len 长度的内容写入到输出流中 outputStream.write(cache, 0, len); } // 关闭流 fileInputStream.close(); outputStream.close(); }else if(postType == "param_file") { String BOUNDARY = java.util.UUID.randomUUID().toString(); String TWO_HYPHENS = "--"; String LINE_END = "\r\n"; httpURLConnection.setRequestProperty("Content-Type","multipart/form-data; BOUNDARY=" + BOUNDARY); // 用连接创建一个输出流 DataOutputStream dataOutputStream = new DataOutputStream(httpURLConnection.getOutputStream()); stringBuffer = new StringBuffer(); // 要发送的数据 String testKey1 = "testVal1"; String testKey2 = "testVal2"; // 封装键值对数据一 stringBuffer.append(TWO_HYPHENS); stringBuffer.append(BOUNDARY); stringBuffer.append(LINE_END); // 发送的参数1的键名为 testKey1,PHP 通过 $_POST['testKey1']; 获取请求参数值为 "testVal1" stringBuffer.append("Content-Disposition: form-data; name=\"" + "testKey1" + "\""); stringBuffer.append(LINE_END); // 发送的参数1类型为文本 stringBuffer.append("Content-Type: " + "text/plain" ); stringBuffer.append(LINE_END); // 发送的参数1的长度 stringBuffer.append("Content-Lenght: " + testKey1.length()); stringBuffer.append(LINE_END); stringBuffer.append(LINE_END); // 发送的参数1的值 stringBuffer.append(testKey1); stringBuffer.append(LINE_END); // 封装键值对数据二 stringBuffer.append(TWO_HYPHENS); stringBuffer.append(BOUNDARY); stringBuffer.append(LINE_END); // 发送的参数2的键名为 testKey2,PHP 通过 $_POST['testKey2']; 获取请求参数值为 "testVal2" stringBuffer.append("Content-Disposition: form-data; name=\"" + "testKey2" + "\""); stringBuffer.append(LINE_END); stringBuffer.append("Content-Type: " + "text/plain" ); stringBuffer.append(LINE_END); stringBuffer.append("Content-Lenght: " + testKey2.length()); stringBuffer.append(LINE_END); stringBuffer.append(LINE_END); stringBuffer.append(testKey2); stringBuffer.append(LINE_END); // 拼接完成后,写入到输出流 dataOutputStream.write(stringBuffer.toString().getBytes()); //拼接文件的参数 stringBuffer = new StringBuffer(); stringBuffer.append(LINE_END); stringBuffer.append(TWO_HYPHENS); stringBuffer.append(BOUNDARY); stringBuffer.append(LINE_END); // 上传文件键名为 testUploadFile,上传文件的文件名为 testFile,PHP 端通过 $_FILES['testUploadFile']['name'] 可获取文件名 "testFile" stringBuffer.append("Content-Disposition: form-data; name=\"" + "testUploadFile" + "\"; filename=\"" + "testFile" + "\""); stringBuffer.append(LINE_END); // 上传文件类型, PHP 端通过 $_FILES['testUploadFile']['type'] 可获取文件类型 "image/jpeg" stringBuffer.append("Content-Type: " + "image/jpeg" ); stringBuffer.append(LINE_END); stringBuffer.append("Content-Lenght: "+uploadFile.length()); stringBuffer.append(LINE_END); stringBuffer.append(LINE_END); dataOutputStream.write(stringBuffer.toString().getBytes()); // 把上传文件封装成一个流 FileInputStream fileInputStream = new FileInputStream(uploadFile); // 每次从输入流实际读取到的字节数 int len = 0; // 定义一个字节数组,相当于缓存,数组长度为1024,即缓存大小为1024个字节 byte[] cache = new byte[1024]; // inputStream.read(cache)) 方法,从输入流中读取最多 cache 数组大小的字节,并将其存储在 cache 中。以整数形式返回实际读取的字节数,当文件读完时返回-1 while((len = fileInputStream.read(cache)) != -1){ // 每次把数组 cache 从 0 到 len 长度的内容写入到输出流中 dataOutputStream.write(cache, 0, len); } // 关闭流 fileInputStream.close(); dataOutputStream.flush(); //写入结束标记位 byte[] endData = (LINE_END + TWO_HYPHENS + BOUNDARY + TWO_HYPHENS + LINE_END).getBytes(); dataOutputStream.write(endData); dataOutputStream.flush(); } } // 发送请求 // connect() 方法可以不用明确调用,因为在调用 getInputStream() 方法时会检查连接是否已经建立,如果没有建立,则会调用 connect() 方法 httpURLConnection.connect(); // 获取所有响应头字段 Map<String, List<String>> map = httpURLConnection.getHeaderFields(); // 遍历所有的响应头字段 for (String key : map.keySet()) { // 显示内容示例 /* Accept-Ranges=====>[bytes] null=====>[HTTP/1.1 200 OK] Server=====>[bfe/1.0.8.18] Etag=====>["588603eb-98b"] Cache-Control=====>[private, no-cache, no-store, proxy-revalidate, no-transform] Connection=====>[Keep-Alive] Set-Cookie=====>[BDORZ=27315; max-age=86400; domain=.baidu.com; path=/] Pragma=====>[no-cache] Last-Modified=====>[Mon, 23 Jan 2017 13:23:55 GMT] Content-Length=====>[2443] Date=====>[Sat, 14 Sep 2019 04:51:29 GMT] Content-Type=====>[text/html] */ System.out.println(key + "=====>" + map.get(key)); } // 通过httpURLConnection连接,获取输入流 if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK) { // HttpURLConnection.HTTP_OK 值即为 200 // 把返回内容读入到内存输入流中 inputStream = httpURLConnection.getInputStream(); if(ResponseType == "str") { // 封装输入流inputStream,并指定字符集 bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8")); // 存放数据 stringBuffer = new StringBuffer(); String temp = null; while ((temp = bufferedReader.readLine()) != null) { stringBuffer.append(temp); //stringBuffer.append("\r\n"); } str_result = stringBuffer.toString(); System.out.println("返回值为 : " + str_result); }else if(ResponseType == "file") { // 获取项目基目录的绝对路径 这里是 D:/ApacheServer/web_java/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/HelloWorld/ String appBase = Thread.currentThread().getContextClassLoader().getResource("../../").toString().substring(6); // 合成下载文件存放目录 这里是 D:/ApacheServer/web_java/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/HelloWorld/downLoad String downLoadPath = appBase + "downLoad"; // 创建目录对象 File fileDir = new File(downLoadPath); if (!fileDir.exists()){ // 目录不存在则创建 fileDir.mkdirs(); } // 在指定目录下创建 file 对象 File file = new File(fileDir, "fileName"); // 将文件对象加载到 文件输出流中,以对文件进行写入操作 FileOutputStream fileOutputStream = new FileOutputStream(file); // 每次从输入流实际读取到的字节数 int len = 0; // 定义一个字节数组,相当于缓存,数组长度为1024 * 8,即缓存大小为1024 * 8个字节 byte[] cache = new byte[1024 * 8]; // inputStream.read(cache)) 方法,从输入流中读取最多 cache 数组大小的字节,并将其存储在 cache 中。以整数形式返回实际读取的字节数,当文件读完时返回-1 while ((len = inputStream.read(cache)) != -1){ // 每次把数组 cache 从 0 到 len 长度的内容写入到文件中 fileOutputStream.write(cache, 0, len); } fileOutputStream.flush(); } } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 关闭资源 if (bufferedReader != null) { try { bufferedReader.close(); } catch (IOException e) { e.printStackTrace(); } } if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } httpURLConnection.disconnect();// 关闭远程连接 } } }