1.1客户端:
HttpClient常用HttpGet和HttpPost这两个类,分别对应Get方式和Post方式。
无论是使用HttpGet,还是使用HttpPost,都必须通过如下3步来访问HTTP资源。
1.创建HttpGet或HttpPost对象,将要请求的URL通过构造方法传入HttpGet或HttpPost对象。
2.使用DefaultHttpClient类的execute方法发送HTTP GET或HTTP POST请求,并返回HttpResponse对象。
3.通过HttpResponse接口的getEntity方法返回响应信息,并进行相应的处理。
package com.qianfeng.uploadfile;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.FormBodyPart;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;
/**
* 文件上传的客户端
* @author qq
*
*/
public class FileUpload {
public FileUpload() {
}
public void fileUpload( final String url,
final File file,
final HashMap<String,String> params,
final String encode,
final CallBack callBack
)
{
new Thread(new Runnable(){
@Override
public void run() {
//使用HttpPost方法提交HTTP POST请求
HttpPost post = new HttpPost(url);
//使用DefaultHttpClient类的execute方法发送HTTP GET或HTTP POST请求,并返回HttpResponse对象。
HttpClient client = new DefaultHttpClient();
//通过HttpResponse接口的getEntity方法返回响应信息,并进行相应的处理。
HttpResponse response = null;
/*
* 在HttpCient4.3之前上传文件主要使用MultipartEntity这个类,
* 但现在这个类已经不在推荐使用了。
* 随之替代它的类是MultipartEntityBuilder。
* */
MultipartEntity entity =new MultipartEntity();
//把文件转换成流对象FileBody
FileBody body = new FileBody(file);
FormBodyPart part = new FormBodyPart("form",body);
//Map通过entrySet()方法来遍历Map集合
for(Map.Entry<String,String> entry:params.entrySet())
{
try {
entity.addPart(entry.getKey(),new StringBody(entry.getValue()));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
entity.addPart(part);//添加数据
post.setEntity(entity);//设置请求参数
try {
//使用DefaultHttpClient类的execute方法发送HTTP POST请求,并返回HttpResponse对象
response = client.execute(post);
if(response.getStatusLine().getStatusCode()==200)//响应码200请求成功
{
//JSON解析
String jsonString = EntityUtils.toString(response.getEntity(),encode);
JSONObject jsonObj = new JSONObject(jsonString);
callBack.getResult(jsonObj);//回调函数
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
}).start();
}
}
interface CallBack
{
void getResult(JSONObject obj);
}
1.2服务器:
一个文件上传请求的消息实体由一系列根据 RFC1867("Form-based File Upload in HTML".)编码的项目(文本参数和文件参数)组成。自己编程来解析获取这些数据是非常麻烦的,还需要了解RFC1867规范对请求数据编码的相关知识。FileUpload 可以帮助我们解析这样的请求,将每一个项目封装成一个实现了FileItem接口的对象,并以列表的形式返回。所以,我们只需要了解FileUpload的API如何使用即可,不用管它们的底层实现。
让我们来看一个简单文件上传处理代码:将UploadServlet发布在服务器上。
package com.qianfeng.servlet;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.json.JSONObject;
public class UploadServlet extends HttpServlet {
/**
* Destruction of the servlet. <br>
*/
public void destroy() {
super.destroy(); // Just puts "destroy" string in log
// Put your code here
}
/**
* The doGet method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to get.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
//实现上传的类
DiskFileItemFactory factory = new DiskFileItemFactory();//磁盘对象
ServletFileUpload upload = new ServletFileUpload(factory);//声明解析request对象
upload.setFileSizeMax(2*1024*1024);//设置每个文件最大为2M
upload.setSizeMax(4*1024*1024);//设置一共最多上传4M
try {
List<FileItem> list = upload.parseRequest(request);//解析
for(FileItem item:list){//判断FileItem类对象封装的数据是一个普通文本表单字段,还是一个文件表单字段,如果是普通表单字段则返回true,否则返回false。
if(!item.isFormField()){
//获取文件名
String fileName = item.getName();
//获取服务器端路径
String file_upload_loader =this.getServletContext().getRealPath("\\upload");
System.out.println("上传文件存放路径:"+file_upload_loader);
//将FileItem对象中保存的主体内容保存到某个指定的文件中。
item.write(new File(file_upload_loader+File.separator+fileName));
}else{
if(item.getFieldName().equalsIgnoreCase("username")){
String username = item.getString("utf-8");//将FileItem对象中保存的数据流内容以一个字符串返回
System.out.println(username);
}
if(item.getFieldName().equalsIgnoreCase("password")){
String password = item.getString("utf-8");
System.out.println(password);
}
}
}
//返回响应码(ResultCode)和响应值(ResultMsg)简单的JSON解析
ResultMessage message = new ResultMessage(1,"上传成功");
JSONObject json = new JSONObject();
JSONObject jsonObject = new JSONObject();
json.put("ResultCode",message.getResultCode());
json.put("ResultMsg",message.getResultMsg());
jsonObject.put("upload"