现在的位置: 首页 > 移动开发 > 正文

Android学习笔记—28_网络通信之通过HTTP协议实现文件上传,组拼http 的post方法,传输内容

2019年09月19日 移动开发 ⁄ 共 39122字 ⁄ 字号 评论关闭

28_网络通信之通过HTTP协议实现文件上传
----------------------------------------------
1.注意,做表单提交的时候:程序代码;
  <form method="post" 

action="http://192.168.1.110:6118/WebGetSetTest/ManagerServlet"  

enctype="multipart/form-data">
标题<input name="title" type="text"/><br/>
时长<input name="timelength" type="text"/><br/>
文件<input name="videofile" type="file"/><br/>
<input value="提交" type="submit"/>
</form>
----------------------------------------------------------------
2.注意在http://192.168.1.110:6118/WebGetSetTest/
  http协议,post指定post方法的时候:boundary=-----------------
  是指定的数据的分割线.根据http协议的要求:
  数据之间要多加两个--号
---------------------------------
3.用IE捕获的信息:
  a.请求标头:
    键
请求 POST /WebGetSetTest/ManagerServlet HTTP/1.1
Accept text/html, application/xhtml+xml, */*
Referer http://192.168.1.110:6118/WebGetSetTest/
Accept-Language zh-CN
User-Agent Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
Content-Type multipart/form-data; 
boundary= ---------------------------7dd33a32e07fc//是指定的数据的分割线
Accept-Encoding gzip, deflate
Host 192.168.1.110:6118
Content-Length 14052
Connection Keep-Alive
Cache-Control no-cache
Cookie JSESSIONID=424D8985791F17DAF67D00AC1FFF26BC
-----------------------------------------------------------------------
b.请求正文:
  -----------------------------7dd33a32e07fc//是指定的数据的分割线,比上面的多了两 

//个--,这是协议规定的
Content-Disposition: form-data; name="title"//指定了参数的名称

lidewei//这是参数的值,参数描述和值之间有两个回车换行
-----------------------------7dd33a32e07fc//是指定的数据的分割线
Content-Disposition: form-data; name="timelength"

598
-----------------------------7dd33a32e07fc
Content-Disposition: form-data; name="videofile"; filename="2.png"
Content-Type: image/jpeg//内容类型

<二进制文件数据未显示>//这里是内容信息
-----------------------------7dd33a32e07fc--//结束线后面有两个--
--------------------------------------------------------
c.响应标头
 键
响应 HTTP/1.1 200 OK
Server Apache-Coyote/1.1
Content-Length 0
Date Thu, 28 Mar 2013 13:57:51 GMT
---------------------------------------------------
d.关于http协议,post的方法:封装的代码:
  可以做为一个通用的方法以后用:
-----------------------------------------
2013-03-29
-----------------------
com.credream.utils
/HttpFileUpload/src/com/credream/utils/FormFile.java
-------------------------------------------------------------
package com.credream.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

/**
 * 上传文件
 */
public class FormFile {
/* 上传文件的数据 */
private byte[] data;
private InputStream inStream;
private File file;
/* 文件名称 */
private String filname;
/* 请求参数名称*/
private String parameterName;
/* 内容类型 */
private String contentType = "application/octet-stream";

//文件比较小的时候用这个方法,这时候就是直接把内存中的数据拿出来,放到磁盘


public FormFile(String filname, byte[] data, String parameterName, String 

contentType) {
this.data = data;
this.filname = filname;
this.parameterName = parameterName;
if(contentType!=null) this.contentType = contentType;
}
//要求传入文件的对象,实现一边读文件,一边上传写到磁盘上,这样不会占用太多内

存,
//上传大文件的时候,一定要用这个方式.
public FormFile(File file, String parameterName, String contentType) {
this.filname = file.getName();
this.parameterName = parameterName;
this.file = file;
try {
this.inStream = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if(contentType!=null) this.contentType = contentType;
}

public File getFile() {
return file;
}

public InputStream getInStream() {
return inStream;
}

public byte[] getData() {
return data;
}

public String getFilname() {
return filname;
}

public void setFilname(String filname) {
this.filname = filname;
}

public String getParameterName() {
return parameterName;
}

public void setParameterName(String parameterName) {
this.parameterName = parameterName;
}

public String getContentType() {
return contentType;
}

public void setContentType(String contentType) {
this.contentType = contentType;
}

}
---------------------------------------------------------------
b./HttpFileUpload/src/com/credream/utils/SocketHttpRequester.java
package com.credream.utils;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

//Content-Length注意这里计算实体数据的总长度的时候,很费劲的,因为
//比如说实体数据为100m的话,那么不可能一次的在内存中得到100m数据的总长度,然后赋值


//Content-Length属性.
/*这里需要用到一些技巧:
先计算,文本类型参数的总长度,然后计算文件类型参数的总长度,然后加上分割线的

总长度

*/
public class SocketHttpRequester {
/**
* 直接通过HTTP协议提交数据到服务器,实现如下面表单提交功能:
*   <FORM METHOD=POST 

ACTION="http://192.168.0.200:8080/ssi/fileload/test.do" enctype="multipart/form-

data">
<INPUT TYPE="text" NAME="name">
<INPUT TYPE="text" NAME="id">
<input type="file" name="imagefile"/>
   <input type="file" name="zip"/>
</FORM>
* @param path 上传路径(注:避免使用localhost或127.0.0.1这样的路径测试,

因为它会指向手机模拟器,你可以使用http://www.itcast.cn或http://192.168.1.10:8080

这样的路径测试)
* @param params 请求参数 key为参数名,value为参数值
* @param file 上传文件
*/
public static boolean post(String path, Map<String, String> params, 

FormFile[] files) throws Exception{     
        final String BOUNDARY = "---------------------------7da2137580612"; //数

据分隔线
        final String endline = "--" + BOUNDARY + "--\r\n";//数据结束标志//注意回

车换行部分
        
        int fileDataLength = 0;
        for(FormFile uploadFile : files){//得到文件类型数据的总长度
        StringBuilder fileExplain = new StringBuilder();
         fileExplain.append("--");
         fileExplain.append(BOUNDARY);
         fileExplain.append("\r\n");
         //以上部分用来完成分割线:  -----------------------------

7dd33a32e07fc
         //注意这里的回车换行
         fileExplain.append("Content-Disposition: form-data;name=\""+ 

uploadFile.getParameterName()+"\";filename=\""+ uploadFile.getFilname() + "\"\r

\n");
         fileExplain.append("Content-Type: "+ uploadFile.getContentType

()+"\r\n\r\n");
       //上面两行用来
      /* Content-Disposition: form-data; name="videofile"; filename="2.png"
Content-Type: image/jpeg*/
         fileDataLength += fileExplain.length();
        /*//通过上面就可以计算下面这个部分的总长度了
        -----------------------------7dd33a32e07fc
       Content-Disposition: form-data; name="videofile"; filename="2.png"
       Content-Type: image/jpeg*/
         if(uploadFile.getInStream()!=null){
        fileDataLength += uploadFile.getFile().length();
   }else{
   
fileDataLength += uploadFile.getData().length;
   }
        fileDataLength += "\r\n".length();
        }
        StringBuilder textEntity = new StringBuilder();
        for (Map.Entry<String, String> entry : params.entrySet()) {//构造文本类型

参数的实体数据
            textEntity.append("--");
            textEntity.append(BOUNDARY);
            textEntity.append("\r\n");
            textEntity.append("Content-Disposition: form-data; name=\""+ 

entry.getKey() + "\"\r\n\r\n");
            textEntity.append(entry.getValue());
            textEntity.append("\r\n");
        }
        //计算传输给服务器的实体数据总长度
        int dataLength = textEntity.toString().getBytes().length + fileDataLength 

+  endline.getBytes().length;
        
        URL url = new URL(path);
        int port = url.getPort()==-1 ? 80 : url.getPort();
        //这里没有用HttpUrlConnection来做,而是直接用socket来做
        //因为HttpUrlConnection使用了缓冲技术,通过这个类给web,应用发送文件的时候
        //这个时候文件首先写入到缓冲里面,很可能导致内存溢出的情况.
       //Socket比HttpUrlConnection底层,没有缓冲区限制
        Socket socket = new Socket(InetAddress.getByName(url.getHost()), port);
 

     
        OutputStream outStream = socket.getOutputStream();
        //下面完成HTTP请求头的发送
        String requestmethod = "POST "+ url.getPath()+" HTTP/1.1\r\n";
        outStream.write(requestmethod.getBytes());
        String accept = "Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, 

application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-

xpsdocument, application/x-ms-xbap, application/x-ms-application, 

application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*

\r\n";
        outStream.write(accept.getBytes());
        String language = "Accept-Language: zh-CN\r\n";
        outStream.write(language.getBytes());
        String contenttype = "Content-Type: multipart/form-data; boundary="+ 

BOUNDARY+ "\r\n";
        outStream.write(contenttype.getBytes());
        String contentlength = "Content-Length: "+ dataLength + "\r\n";
        outStream.write(contentlength.getBytes());
        String alive = "Connection: Keep-Alive\r\n";
        outStream.write(alive.getBytes());
        String host = "Host: "+ url.getHost() +":"+ port +"\r\n";
        outStream.write(host.getBytes());
        //写完HTTP请求头后根据HTTP协议再写一个回车换行
        outStream.write("\r\n".getBytes());
        //把所有文本类型的实体数据发送出来
        outStream.write(textEntity.toString().getBytes());
      
        //把所有文件类型的实体数据发送出来
        for(FormFile uploadFile : files){
        StringBuilder fileEntity = new StringBuilder();
         fileEntity.append("--");
         fileEntity.append(BOUNDARY);
         fileEntity.append("\r\n");
         fileEntity.append("Content-Disposition: form-data;name=\""+ 

uploadFile.getParameterName()+"\";filename=\""+ uploadFile.getFilname() + "\"\r

\n");
         fileEntity.append("Content-Type: "+ uploadFile.getContentType

()+"\r\n\r\n");
         outStream.write(fileEntity.toString().getBytes());
         if(uploadFile.getInStream()!=null){
         
byte[] buffer = new byte[1024];
         
int len = 0;
         
while((len = uploadFile.getInStream().read(buffer, 0, 

1024))!=-1){
         
outStream.write(buffer, 0, len);
         
}
         
uploadFile.getInStream().close();
         }else{
         
outStream.write(uploadFile.getData(), 0, 

uploadFile.getData().length);
         }
         outStream.write("\r\n".getBytes());
        }
        //下面发送数据结束标志,表示数据已经结束
        outStream.write(endline.getBytes());
        
        BufferedReader reader = new BufferedReader(new InputStreamReader

(socket.getInputStream()));
        if(reader.readLine().indexOf("200")==-1){//读取web服务器返回的数据,判断

请求码是否为200,如果不是200,代表请求失败
        return false;
        }
        outStream.flush();
        outStream.close();
        reader.close();
        socket.close();
        return true;
}

/**
* 提交数据到服务器
* @param path 上传路径(注:避免使用localhost或127.0.0.1这样的路径测试,

因为它会指向手机模拟器,你可以使用http://www.itcast.cn或http://192.168.1.10:8080

这样的路径测试)
* @param params 请求参数 key为参数名,value为参数值
* @param file 上传文件
*/
public static boolean post(String path, Map<String, String> params, 

FormFile file) throws Exception{
  return post(path, params, new FormFile[]{file});
}
/**
* 提交数据到服务器
* @param path 上传路径(注:避免使用localhost或127.0.0.1这样的路径测试,

因为它会指向手机模拟器,你可以使用http://www.itcast.cn或http://192.168.1.10:8080

这样的路径测试)
* @param params 请求参数 key为参数名,value为参数值
* @param encode 编码
*/
public static byte[] postFromHttpClient(String path, Map<String, String> 

params, String encode) throws Exception{
List<NameValuePair> formparams = new ArrayList<NameValuePair>

();//用于存放请求参数
for(Map.Entry<String, String> entry : params.entrySet()){
formparams.add(new BasicNameValuePair(entry.getKey(), 

entry.getValue()));
}
UrlEncodedFormEntity entity = new UrlEncodedFormEntity

(formparams, encode);
HttpPost httppost = new HttpPost(path);
httppost.setEntity(entity);
HttpClient httpclient = new DefaultHttpClient();//看作是浏览器
HttpResponse response = httpclient.execute(httppost);//发送post请


return readStream(response.getEntity().getContent());
}

/**
* 发送请求
* @param path 请求路径
* @param params 请求参数 key为参数名称 value为参数值
* @param encode 请求参数的编码
*/
public static byte[] post(String path, Map<String, String> params, String 

encode) throws Exception{
//String params = "method=save&name="+ URLEncoder.encode("老毕", 

"UTF-8")+ "&age=28&";//需要发送的参数
StringBuilder parambuilder = new StringBuilder("");
if(params!=null && !params.isEmpty()){
for(Map.Entry<String, String> entry : params.entrySet()){
parambuilder.append(entry.getKey()).append("=")
.append(URLEncoder.encode(entry.getValue

(), encode)).append("&");
}
parambuilder.deleteCharAt(parambuilder.length()-1);
}
byte[] data = parambuilder.toString().getBytes();
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setDoOutput(true);//允许对外发送请求参数
conn.setUseCaches(false);//不进行缓存
conn.setConnectTimeout(5 * 1000);
conn.setRequestMethod("POST");
//下面设置http请求头
conn.setRequestProperty("Accept", "image/gif, image/jpeg, 

image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, 

application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-

application, application/vnd.ms-excel, application/vnd.ms-powerpoint, 

application/msword, */*");
conn.setRequestProperty("Accept-Language", "zh-CN");
conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; 

MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; 

.NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
conn.setRequestProperty("Content-Type", "application/x-www-form-

urlencoded");
conn.setRequestProperty("Content-Length", String.valueOf

(data.length));
conn.setRequestProperty("Connection", "Keep-Alive");

//发送参数
DataOutputStream outStream = new DataOutputStream

(conn.getOutputStream());
outStream.write(data);//把参数发送出去
outStream.flush();
outStream.close();
if(conn.getResponseCode()==200){
return readStream(conn.getInputStream());
}
return null;
}

/**
* 读取流
* @param inStream
* @return 字节数组
* @throws Exception
*/
public static byte[] readStream(InputStream inStream) throws Exception{
ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = -1;
while( (len=inStream.read(buffer)) != -1){
outSteam.write(buffer, 0, len);
}
outSteam.close();
inStream.close();
return outSteam.toByteArray();
}
}
----------------------------------------------------------------
2.对于:28_网络通信之通过HTTP协议实现文件上传的所有代码
-----------------------------------------
1.新建Android项目:HttpFileUpload项目
---------------
/HttpFileUpload/src/com/credream/newmanager/NewsGetSetManagerActivity.java
package com.credream.newmanager;

import java.io.File;

import com.credream.service.NewsService;

import android.app.Activity;

import android.os.Bundle;

import android.os.Environment;

import android.view.View;

import android.widget.EditText;

import android.widget.Toast;

public class NewsGetSetManagerActivity extends Activity {
 
   /** Called when the activity is first created. */
 
private EditText titleText;

 private EditText timelengthText;

 private EditText nameText;

@Override
    
public void onCreate(Bundle savedInstanceState) {
  
      super.onCreate(savedInstanceState);
   
     setContentView(R.layout.main);
  
     titleText=(EditText) this.findViewById(R.id.title);
  
    timelengthText= (EditText)this.findViewById(R.id.timelength);
 
     nameText= (EditText)this.findViewById(R.id.filename);
  
  }
    
    
public void save(View v){
    
String filename= nameText.getText().toString();
    
String title= titleText.getText().toString();
   
String length=timelengthText.getText().toString();
   
  
  //判断有没有sd卡,当有sd卡,和sd为只读的时候,可以执行
  
  if(Environment.getExternalStorageState().equals

(Environment.MEDIA_MOUNTED)||
   

Environment.getExternalStorageState().equals

(Environment.MEDIA_MOUNTED_READ_ONLY)){
    
File uploadFile =
new File(Environment.getExternalStorageDirectory

(),filename);
    
if(uploadFile.exists()){//调用方法进行保存文件
    
boolean result=
NewsService.save(title,length,uploadFile);
   
  if(result){//
   
Toast.makeText(getApplicationContext(), R.string.success, 1).show();
   

}else {

Toast.makeText(getApplicationContext(), R.string.error, 1).show();
}
 

   }else {

Toast.makeText(getApplicationContext(), R.string.filenoexsit, 1).show();


}
    
}else {//当sdk不存在的时候
    
boolean result=NewsService.save(title,length);//用这样业务类,进行

保存
        if(result){
       
  Toast.makeText(getApplicationContext(), R.string.success,1).show

();
        
}else {
   
Toast.makeText(getApplicationContext(), R.string.error, 1).show

();
   
}

}
   
   
 }
}
------------------------------------------------------------------------------
2./HttpFileUpload/src/com/credream/service/NewsService.java
package com.credream.service;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import com.credream.utils.FormFile;
import com.credream.utils.SocketHttpRequester;

import android.media.MediaRecorder.OutputFormat;
import android.provider.ContactsContract.Contacts.Data;

public class NewsService
{
/**
* 保存数据
* @param title 标题
* @param length 时长
* @return
*/
public static boolean save(String title, String length)
{
String 

path="http://192.168.1.110:6118/WebGetSetTest/ManagerServlet";
   Map<String, String>  params=new HashMap<String, String>();
   params.put("title", title);
   params.put("timelength", length);
   try{
//return sendGetRequest(path,params);
//return sendGetRequest(path,params,"UTF-8");
  //return sendPOSTRequest(path,params,"UTF-8");
  return sendHttpClientRequest(path,params,"UTF-8");
   }catch(Exception e){
  e.printStackTrace();
   }
   return false;
   }
/**通过httpClient的时候,发送post请求
*使用httpClient的时候,不需要导入jar文件,因为android,已经集成了这个功能
* @param path
* @param params
* @param string
* @return
* @throws IOException 
*/
private static boolean sendHttpClientRequest(String path,
Map<String, String> params, String coding) throws 

IOException
{
List<NameValuePair> pairs=new ArrayList<NameValuePair>();//存放请

求参数
if(params!=null && !params.isEmpty()){
for(Map.Entry<String, String> entry:params.entrySet()){
pairs.add(new BasicNameValuePair(entry.getKey(), 

entry.getValue()));
}
}
//采用
//编码
UrlEncodedFormEntity entity=new UrlEncodedFormEntity

(pairs,coding);
HttpPost httpPost=new HttpPost(path);
httpPost.setEntity(entity);
DefaultHttpClient client=new DefaultHttpClient();
//可以看做一个浏览器
HttpResponse response=client.execute(httpPost);
if (response.getStatusLine().getStatusCode()==200)
{
return true;
}

return false;
}
/**
* 发送post请求
* @param path 请求路径
* @param params 请求参数
* @param string 编码
* @return 请求是否成功
* @throws Exception 
*/
private static boolean sendPOSTRequest(String path,Map<String, String> params, 

String coding) throws Exception
{
//title=lidewei&timelength=90
StringBuilder data=new StringBuilder();
if(params!=null && !params.isEmpty()){
for(Map.Entry<String, String> entry:params.entrySet()){
data.append(entry.getKey()).append("=");
//url.append(entry.getValue());
data.append(URLEncoder.encode(entry.getValue(), coding));
//乱码的第一个因素,对传来的字符串进行编码
data.append("&");
}
data.deleteCharAt(data.length()-1);
}
byte[] entity=data.toString().getBytes();//得到实体数据
  HttpURLConnection conn= (HttpURLConnection) new URL(path).openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("POST");
conn.setDoOutput(true);//允许
conn.setRequestProperty("Content-Type", "application/x-www-form-

urlencoded");
conn.setRequestProperty("Content-Length", String.valueOf(entity.length));
OutputStream outputStream=conn.getOutputStream();
outputStream.write(entity);//数据写到了缓存中
//只有在我们取得响应的http协议的某个部分的时候,请求才会真正的发送出去.
if (conn.getResponseCode()==200)
{
return true;

}
return false;
}
//组拼字符串http://localhost:6118/WebGetSetTest/ManagerServlet?

title=xiaofeng&timelength=80
/**
 * 发送GET请求
 * @param path 请求路径
 * @param params 请求参数
 * @return  请求是否成功
 * @throws Exception 
 */
//private static boolean sendGetRequest(String path,Map<String, String> 

params)throws Exception{
//没有修改前会出现乱码
private static boolean sendGetRequest(String path,Map<String, String> 

params,String coding)throws Exception{
StringBuilder url=new StringBuilder(path);
url.append("?");
for(Map.Entry<String, String> entry:params.entrySet()){
url.append(entry.getKey()).append("=");
//url.append(entry.getValue());
url.append(URLEncoder.encode(entry.getValue(), coding));
//乱码的第一个因素,对传来的字符串进行编码
//
url.append("&");
}
url.deleteCharAt(url.length()-1);
HttpURLConnection conn=(HttpURLConnection)new URL(url.toString

()).openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
if(conn.getResponseCode()==200){
return true;
}
return false;
}
//用来上传文件的save方法测试
public static boolean save(String title, String length, File uploadFile)
{
String path="http://192.168.1.110:6118/WebGetSetTest/ManagerServlet";
  Map<String, String>  params=new HashMap<String, String>();
  params.put("title", title);
  params.put("timelength", length);
  FormFile formFile=new FormFile(uploadFile, "videofile", "image/gif");
  //jpg的就写 "image/jpeg"
  //注意这里的第三个参数类型,如果想根据用户输入不同文件,比如用户输入的事

图片文件
  //对应的类型就是image/jpeg,用户输入的是可执行文件exe,对应的就是....
  //那么这里需要建立字典,比如tomcat就是通过建立字典判断文件类型的
  /*//
   * 在tomcat的配置文件中:G:\apache-tomcat-6.0.10\conf\web.xml
  <mime-mapping>
       <extension>jpeg</extension>
       <mime-type>image/jpeg</mime-type>
   </mime-mapping>
   <mime-mapping>
       <extension>jpg</extension>
       <mime-type>image/jpeg</mime-type>
   </mime-mapping>*/
  try{
  return SocketHttpRequester.post(path,params,formFile);
  }catch(Exception e){
  e.printStackTrace();
  }
  return false;
//这个方法.
}

}
-------------------------------------------------------------------------
3./HttpFileUpload/src/com/credream/utils/FormFile.java
package com.credream.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

/**
 * 上传文件
 */
public class FormFile {
/* 上传文件的数据 */
private byte[] data;
private InputStream inStream;
private File file;
/* 文件名称 */
private String filname;
/* 请求参数名称*/
private String parameterName;
/* 内容类型 */
private String contentType = "application/octet-stream";

//文件比较小的时候用这个方法,这时候就是直接把内存中的数据拿出来,放到磁盘


public FormFile(String filname, byte[] data, String parameterName, String 

contentType) {
this.data = data;
this.filname = filname;
this.parameterName = parameterName;
if(contentType!=null) this.contentType = contentType;
}
//要求传入文件的对象,实现一边读文件,一边上传写到磁盘上,这样不会占用太多内

存,
//上传大文件的时候,一定要用这个方式.
public FormFile(File file, String parameterName, String contentType) {
this.filname = file.getName();
this.parameterName = parameterName;
this.file = file;
try {
this.inStream = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if(contentType!=null) this.contentType = contentType;
}

public File getFile() {
return file;
}

public InputStream getInStream() {
return inStream;
}

public byte[] getData() {
return data;
}

public String getFilname() {
return filname;
}

public void setFilname(String filname) {
this.filname = filname;
}

public String getParameterName() {
return parameterName;
}

public void setParameterName(String parameterName) {
this.parameterName = parameterName;
}

public String getContentType() {
return contentType;
}

public void setContentType(String contentType) {
this.contentType = contentType;
}

}
----------------------------------------------------------------------
4./HttpFileUpload/src/com/credream/utils/SocketHttpRequester.java
package com.credream.utils;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

//Content-Length注意这里计算实体数据的总长度的时候,很费劲的,因为
//比如说实体数据为100m的话,那么不可能一次的在内存中得到100m数据的总长度,然后赋值


//Content-Length属性.
/*这里需要用到一些技巧:
先计算,文本类型参数的总长度,然后计算文件类型参数的总长度,然后加上分割线的

总长度

*/
public class SocketHttpRequester {
/**
* 直接通过HTTP协议提交数据到服务器,实现如下面表单提交功能:
*   <FORM METHOD=POST 

ACTION="http://192.168.0.200:8080/ssi/fileload/test.do" enctype="multipart/form-

data">
<INPUT TYPE="text" NAME="name">
<INPUT TYPE="text" NAME="id">
<input type="file" name="imagefile"/>
   <input type="file" name="zip"/>
</FORM>
* @param path 上传路径(注:避免使用localhost或127.0.0.1这样的路径测试,

因为它会指向手机模拟器,你可以使用http://www.itcast.cn或http://192.168.1.10:8080

这样的路径测试)
* @param params 请求参数 key为参数名,value为参数值
* @param file 上传文件
*/
public static boolean post(String path, Map<String, String> params, 

FormFile[] files) throws Exception{     
        final String BOUNDARY = "---------------------------7da2137580612"; //数

据分隔线
        final String endline = "--" + BOUNDARY + "--\r\n";//数据结束标志//注意回

车换行部分
        
        int fileDataLength = 0;
        for(FormFile uploadFile : files){//得到文件类型数据的总长度
        StringBuilder fileExplain = new StringBuilder();
         fileExplain.append("--");
         fileExplain.append(BOUNDARY);
         fileExplain.append("\r\n");
         //以上部分用来完成分割线:  -----------------------------

7dd33a32e07fc
         //注意这里的回车换行
         fileExplain.append("Content-Disposition: form-data;name=\""+ 

uploadFile.getParameterName()+"\";filename=\""+ uploadFile.getFilname() + "\"\r

\n");
         fileExplain.append("Content-Type: "+ uploadFile.getContentType

()+"\r\n\r\n");
       //上面两行用来
      /* Content-Disposition: form-data; name="videofile"; filename="2.png"
Content-Type: image/jpeg*/
         fileDataLength += fileExplain.length();
        /*//通过上面就可以计算下面这个部分的总长度了
        -----------------------------7dd33a32e07fc
       Content-Disposition: form-data; name="videofile"; filename="2.png"
       Content-Type: image/jpeg*/
         if(uploadFile.getInStream()!=null){
        fileDataLength += uploadFile.getFile().length();
   }else{
   
fileDataLength += uploadFile.getData().length;
   }
        fileDataLength += "\r\n".length();
        }
        StringBuilder textEntity = new StringBuilder();
        for (Map.Entry<String, String> entry : params.entrySet()) {//构造文本类型

参数的实体数据
            textEntity.append("--");
            textEntity.append(BOUNDARY);
            textEntity.append("\r\n");
            textEntity.append("Content-Disposition: form-data; name=\""+ 

entry.getKey() + "\"\r\n\r\n");
            textEntity.append(entry.getValue());
            textEntity.append("\r\n");
        }
        //计算传输给服务器的实体数据总长度
        int dataLength = textEntity.toString().getBytes().length + fileDataLength 

+  endline.getBytes().length;
        
        URL url = new URL(path);
        int port = url.getPort()==-1 ? 80 : url.getPort();
        //这里没有用HttpUrlConnection来做,而是直接用socket来做
        //因为HttpUrlConnection使用了缓冲技术,通过这个类给web,应用发送文件的时候
        //这个时候文件首先写入到缓冲里面,很可能导致内存溢出的情况.
       //Socket比HttpUrlConnection底层,没有缓冲区限制
        Socket socket = new Socket(InetAddress.getByName(url.getHost()), port);
 

     
        OutputStream outStream = socket.getOutputStream();
        //下面完成HTTP请求头的发送
        String requestmethod = "POST "+ url.getPath()+" HTTP/1.1\r\n";
        outStream.write(requestmethod.getBytes());
        String accept = "Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, 

application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-

xpsdocument, application/x-ms-xbap, application/x-ms-application, 

application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*

\r\n";
        outStream.write(accept.getBytes());
        String language = "Accept-Language: zh-CN\r\n";
        outStream.write(language.getBytes());
        String contenttype = "Content-Type: multipart/form-data; boundary="+ 

BOUNDARY+ "\r\n";
        outStream.write(contenttype.getBytes());
        String contentlength = "Content-Length: "+ dataLength + "\r\n";
        outStream.write(contentlength.getBytes());
        String alive = "Connection: Keep-Alive\r\n";
        outStream.write(alive.getBytes());
        String host = "Host: "+ url.getHost() +":"+ port +"\r\n";
        outStream.write(host.getBytes());
        //写完HTTP请求头后根据HTTP协议再写一个回车换行
        outStream.write("\r\n".getBytes());
        //把所有文本类型的实体数据发送出来
        outStream.write(textEntity.toString().getBytes());
      
        //把所有文件类型的实体数据发送出来
        for(FormFile uploadFile : files){
        StringBuilder fileEntity = new StringBuilder();
         fileEntity.append("--");
         fileEntity.append(BOUNDARY);
         fileEntity.append("\r\n");
         fileEntity.append("Content-Disposition: form-data;name=\""+ 

uploadFile.getParameterName()+"\";filename=\""+ uploadFile.getFilname() + "\"\r

\n");
         fileEntity.append("Content-Type: "+ uploadFile.getContentType

()+"\r\n\r\n");
         outStream.write(fileEntity.toString().getBytes());
         if(uploadFile.getInStream()!=null){
         
byte[] buffer = new byte[1024];
         
int len = 0;
         
while((len = uploadFile.getInStream().read(buffer, 0, 

1024))!=-1){
         
outStream.write(buffer, 0, len);
         
}
         
uploadFile.getInStream().close();
         }else{
         
outStream.write(uploadFile.getData(), 0, 

uploadFile.getData().length);
         }
         outStream.write("\r\n".getBytes());
        }
        //下面发送数据结束标志,表示数据已经结束
        outStream.write(endline.getBytes());
        
        BufferedReader reader = new BufferedReader(new InputStreamReader

(socket.getInputStream()));
        if(reader.readLine().indexOf("200")==-1){//读取web服务器返回的数据,判断

请求码是否为200,如果不是200,代表请求失败
        return false;
        }
        outStream.flush();
        outStream.close();
        reader.close();
        socket.close();
        return true;
}

/**
* 提交数据到服务器
* @param path 上传路径(注:避免使用localhost或127.0.0.1这样的路径测试,

因为它会指向手机模拟器,你可以使用http://www.itcast.cn或http://192.168.1.10:8080

这样的路径测试)
* @param params 请求参数 key为参数名,value为参数值
* @param file 上传文件
*/
public static boolean post(String path, Map<String, String> params, 

FormFile file) throws Exception{
  return post(path, params, new FormFile[]{file});
}
/**
* 提交数据到服务器
* @param path 上传路径(注:避免使用localhost或127.0.0.1这样的路径测试,

因为它会指向手机模拟器,你可以使用http://www.itcast.cn或http://192.168.1.10:8080

这样的路径测试)
* @param params 请求参数 key为参数名,value为参数值
* @param encode 编码
*/
public static byte[] postFromHttpClient(String path, Map<String, String> 

params, String encode) throws Exception{
List<NameValuePair> formparams = new ArrayList<NameValuePair>

();//用于存放请求参数
for(Map.Entry<String, String> entry : params.entrySet()){
formparams.add(new BasicNameValuePair(entry.getKey(), 

entry.getValue()));
}
UrlEncodedFormEntity entity = new UrlEncodedFormEntity

(formparams, encode);
HttpPost httppost = new HttpPost(path);
httppost.setEntity(entity);
HttpClient httpclient = new DefaultHttpClient();//看作是浏览器
HttpResponse response = httpclient.execute(httppost);//发送post请


return readStream(response.getEntity().getContent());
}

/**
* 发送请求
* @param path 请求路径
* @param params 请求参数 key为参数名称 value为参数值
* @param encode 请求参数的编码
*/
public static byte[] post(String path, Map<String, String> params, String 

encode) throws Exception{
//String params = "method=save&name="+ URLEncoder.encode("老毕", 

"UTF-8")+ "&age=28&";//需要发送的参数
StringBuilder parambuilder = new StringBuilder("");
if(params!=null && !params.isEmpty()){
for(Map.Entry<String, String> entry : params.entrySet()){
parambuilder.append(entry.getKey()).append("=")
.append(URLEncoder.encode(entry.getValue

(), encode)).append("&");
}
parambuilder.deleteCharAt(parambuilder.length()-1);
}
byte[] data = parambuilder.toString().getBytes();
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setDoOutput(true);//允许对外发送请求参数
conn.setUseCaches(false);//不进行缓存
conn.setConnectTimeout(5 * 1000);
conn.setRequestMethod("POST");
//下面设置http请求头
conn.setRequestProperty("Accept", "image/gif, image/jpeg, 

image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, 

application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-

application, application/vnd.ms-excel, application/vnd.ms-powerpoint, 

application/msword, */*");
conn.setRequestProperty("Accept-Language", "zh-CN");
conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; 

MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; 

.NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
conn.setRequestProperty("Content-Type", "application/x-www-form-

urlencoded");
conn.setRequestProperty("Content-Length", String.valueOf

(data.length));
conn.setRequestProperty("Connection", "Keep-Alive");

//发送参数
DataOutputStream outStream = new DataOutputStream

(conn.getOutputStream());
outStream.write(data);//把参数发送出去
outStream.flush();
outStream.close();
if(conn.getResponseCode()==200){
return readStream(conn.getInputStream());
}
return null;
}

/**
* 读取流
* @param inStream
* @return 字节数组
* @throws Exception
*/
public static byte[] readStream(InputStream inStream) throws Exception{
ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = -1;
while( (len=inStream.read(buffer)) != -1){
outSteam.write(buffer, 0, len);
}
outSteam.close();
inStream.close();
return outSteam.toByteArray();
}
}
----------------------------------------------------------------------------
5./HttpFileUpload/res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/title" />
    <EditText 
          android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/title"
        />
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/timelength" />
     
    <EditText 
          android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:numeric="integer"
        android:id="@+id/timelength"
        />
    <!--  android:numeric="integer",指定时长只能输入整形的数据 -->
    
    
      <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/filename" />
     
    <EditText 
          android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/filename"
        />
    
    <Button 
          android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/button"
       android:onClick="save"
        android:id="@+id/button"
        />
    <!-- android:id="@+id/button"当点击button的时候执行这个方法 -->

</LinearLayout>
---------------------------------------------------------------------
6./HttpFileUpload/res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="hello">Hello World, NewsGetSetManagerActivity!</string>
    <string name="app_name">利用getSet方法给web应用传值</string>
    <string name="title">视频标题</string>
    <string name="timelength">时长</string>
    <string name="button">保存</string>
    <string name="success">保存成功</string>
    <string name="error">保存失败</string>
<string name="filename">文件名称</string>
<string name="filenoexsit">文件不存在</string>
</resources>
------------------------------------------------------------------
7./HttpFileUpload/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.credream.newmanager"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name=".NewsGetSetManagerActivity" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
 <!--访问网络权限-->
    <uses-permission android:name="android.permission.INTERNET"/>
</manifest>
-------------------------------------------------------------------------------
7.新建web项目:HttpFileUploadTest
/HttpFileUploadTest/src/com/credram/servlet/ManagerServlet.java
package com.credram.servlet;

import java.io.File;
import java.io.IOException;
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.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
/**
 * Servlet implementation class ManagerServlet
 */
public class ManagerServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse 

response) throws ServletException, IOException {
String title= request.getParameter("title");
  //当使用了filter就没必要再转码了:
//title=new String(title.getBytes("ISO8859-1"),"UTF-8") ;
//1.这样可以使得tomcat改变以iso8859-1的编码对接收到的数据进行解码

.以解决乱码问题
String timelength=request.getParameter("timelength");
System.out.println("视频名称:"+title);
System.out.println("时长:"+timelength);
}

/**
* @see HttpServlet#doPost(HttpServletRequest request, 

HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse 

response) throws ServletException, IOException {
//
boolean isMultipart = ServletFileUpload.isMultipartContent

(request);
if(isMultipart){
try
{
//判断类型,上传文件类型
// Create a factory for disk-based file items
FileItemFactory factory = new 

DiskFileItemFactory();
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload

(factory);
String dir=  request.getSession

().getServletContext().getRealPath("/files");
File dirFile=new File(dir);
if(!dirFile.exists()){
dirFile.mkdirs();//如果没有这个文件夹就

创建
}
// Parse the request
                /* FileItem */ 
List<FileItem>
items = upload.parseRequest

(request);

for(FileItem item:items){
if (item.isFormField()) {//文本类型参数
//............
       //processFormField(item);
String name = item.getFieldName();
       String value = item.getString();
       System.out.println(name+value+" all 

data");
   } else {//如果是文件类型参数,执行
    //................
    //processUploadedFile(item);

   System.out.println(dir);
   File saveFile=new File(dirFile,item.getName

());//第一个目录,第二个文件名字
   item.write(saveFile);
   }
}
} catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}else {

}
doGet(request, response);
}

}
--------------------------------------------------------------------------
2./HttpFileUploadTest/src/com/credream/filter/EncodingFilter.java
package com.credream.filter;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

public class EncodingFilter implements Filter {
public void destroy() {
// 销毁的时候调用
}
 
public void doFilter(ServletRequest request, ServletResponse response, 

FilterChain chain) throws IOException, ServletException {
//每一次请求到来的时候都会调用这个方法
HttpServletRequest req=(HttpServletRequest) request;
if("GET".equals(req.getMethod())){
EncodingHttpServletRequest wrapper=new 

EncodingHttpServletRequest(req);
chain.doFilter(wrapper, response);
}else {
req.setCharacterEncoding("UTF-8");
//解决乱码问题
chain.doFilter(request, response);
}
//--request请求对象--->Filter--->wrapper包装后的request对象--

>servlet-->这时候调用的request是包装后的request

}

 
public void init(FilterConfig fConfig) throws ServletException {
// 当web应用启动的时候就会调用这个方法

}

}
-------------------------------------------------------------------
3./HttpFileUploadTest/src/com/credream/filter/EncodingHttpServletRequest.java
package com.credream.filter;

import java.io.UnsupportedEncodingException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class EncodingHttpServletRequest extends HttpServletRequestWrapper
{
private HttpServletRequest request;
public EncodingHttpServletRequest(HttpServletRequest request)
{
super(request);
 this.request=request;
}
@Override
public String getParameter(String name)
{
String value=request.getParameter(name);
if(value!=null){
try
{
value=new String(value.getBytes("ISO8859-1"),"UTF-8");
} catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
}
return value;
}
}
--------------------------------------------------------------------
4./HttpFileUploadTest/WebContent/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

xmlns="http://java.sun.com/xml/ns/javaee" 

xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 

http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>VideoNews</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <description></description>
    <display-name>ListServlet</display-name>
    <servlet-name>ListServlet</servlet-name>
    <servlet-class>com.credram.servlet.ListServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ListServlet</servlet-name>
    <url-pattern>/ListServlet</url-pattern>
  </servlet-mapping>
  <servlet>
    <description></description>
    <display-name>ManagerServlet</display-name>
    <servlet-name>ManagerServlet</servlet-name>
    <servlet-class>com.credram.servlet.ManagerServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ManagerServlet</servlet-name>
    <url-pattern>/ManagerServlet</url-pattern>
  </servlet-mapping>
  <filter>
  <filter-name>myfilter</filter-name>
  <filter-class>com.credream.filter.EncodingFilter</filter-class>
  </filter>
  <filter-mapping>
  <filter-name>myfilter</filter-name>
  <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>
----------------------------------------------------------------------

  

抱歉!评论已关闭.