我想编写Java应用程序,它将使用PHP将文件上传到Apache服务器。Java代码使用Jakarta HttpClient库版本4.0 beta2:
import java.io.File; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.FileEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.CoreProtocolPNames; import org.apache.http.util.EntityUtils; public class PostFile { public static void main(String[] args) throws Exception { HttpClient httpclient = new DefaultHttpClient(); httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1); HttpPost httppost = new HttpPost("http://localhost:9002/upload.php"); File file = new File("c:/TRASH/zaba_1.jpg"); FileEntity reqEntity = new FileEntity(file, "binary/octet-stream"); httppost.setEntity(reqEntity); reqEntity.setContentType("binary/octet-stream"); System.out.println("executing request " + httppost.getRequestLine()); HttpResponse response = httpclient.execute(httppost); HttpEntity resEntity = response.getEntity(); System.out.println(response.getStatusLine()); if (resEntity != null) { System.out.println(EntityUtils.toString(resEntity)); } if (resEntity != null) { resEntity.consumeContent(); } httpclient.getConnectionManager().shutdown(); } }
PHP文件upload.php非常简单:
upload.php
<?php if (is_uploaded_file($_FILES['userfile']['tmp_name'])) { echo "File ". $_FILES['userfile']['name'] ." uploaded successfully.\n"; move_uploaded_file ($_FILES['userfile'] ['tmp_name'], $_FILES['userfile'] ['name']); } else { echo "Possible file upload attack: "; echo "filename '". $_FILES['userfile']['tmp_name'] . "'."; print_r($_FILES); } ?>
阅读响应,我得到以下结果:
executing request POST http://localhost:9002/upload.php HTTP/1.1 HTTP / 1.1 200 OK 可能的文件上传攻击:文件名“。 数组 ( )
这样请求就成功了,我可以与服务器通信了,但是PHP没有注意到文件- is_uploaded_file返回的方法false和$_FILES变量为空。我不知道为什么会这样。我已经跟踪了HTTP响应和请求,它们看起来还不错: 请求是:
is_uploaded_file
false
$_FILES
POST /upload.php HTTP / 1.1 内容长度:13091 内容类型:二进制/八位字节流 主机:localhost:9002 连接:保持活动 用户代理:Apache-HttpClient / 4.0-beta2(java 1.5) 期望:100-继续 ˙Ř˙ŕ.....其余的二进制文件...
和回应:
HTTP / 1.1 100继续 HTTP / 1.1 200 OK 日期:2009年7月1日星期三06:51:57 GMT 服务器:Apache / 2.2.8(Win32)DAV / 2 mod_ssl / 2.2.8 OpenSSL / 0.9.8g mod_autoindex_color PHP / 5.2.5 mod_jk / 1.2.26 X-Powered-By:PHP / 5.2.5 内容长度:51 保持活动:超时= 5,最大= 100 连接:保持活动 内容类型:text / html 可能的文件上传攻击:文件名''.Array ( )
我正在使用xampp的本地Windows XP和远程Linux服务器上对此进行测试。我还尝试使用HttpClient的早期版本-版本3.1- is_uploaded_file返回的结果更加不清楚false,但是$_FILES数组中填充了正确的数据。
好的,我使用的Java代码是错误的,这里是正确的Java类:
import java.io.File; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.mime.MultipartEntity; import org.apache.http.entity.mime.content.ContentBody; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.CoreProtocolPNames; import org.apache.http.util.EntityUtils; public class PostFile { public static void main(String[] args) throws Exception { HttpClient httpclient = new DefaultHttpClient(); httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1); HttpPost httppost = new HttpPost("http://localhost:9001/upload.php"); File file = new File("c:/TRASH/zaba_1.jpg"); MultipartEntity mpEntity = new MultipartEntity(); ContentBody cbFile = new FileBody(file, "image/jpeg"); mpEntity.addPart("userfile", cbFile); httppost.setEntity(mpEntity); System.out.println("executing request " + httppost.getRequestLine()); HttpResponse response = httpclient.execute(httppost); HttpEntity resEntity = response.getEntity(); System.out.println(response.getStatusLine()); if (resEntity != null) { System.out.println(EntityUtils.toString(resEntity)); } if (resEntity != null) { resEntity.consumeContent(); } httpclient.getConnectionManager().shutdown(); } }
注意使用MultipartEntity。