
本实例实现每隔5秒上传一次,通过服务器端获取手机上传过来的文件信息并做相应处理;采用AndroID+Struts2技术。
一、AndroID端实现文件上传
1)、新建一个AndroID项目命名为androIDUpload,目录结构如下:
2)、新建Formfile类,用来封装文件信息
package com.ljq.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(String filname,file file,String ContentType) { this.filname = filname; 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; } }3)、新建SockethttpRequester类,封装上传文件到服务器代码
package com.ljq.utils;import java.io.BufferedReader;import java.io.inputStreamReader;import java.io.OutputStream;import java.net.InetAddress;import java.net.socket;import java.net.URL;import java.util.Map;/** * 上传文件到服务器 * * @author administrator * */public class SockethttpRequester { /** * 直接通过http协议提交数据到服务器,实现如下面表单提交功能: * <FORM METHOD=POST ACTION="http://192.168.1.101:8083/upload/servlet/UploadServlet" 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.iteye.cn或http://192.168.1.101:8083这样的路径测试) * @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"); fileExplain.append("Content-disposition: form-data;name=\""+ uploadfile.getParametername()+"\";filename=\""+ uploadfile.getFilname() + "\"\r\n"); fileExplain.append("Content-Type: "+ uploadfile.getContentType()+"\r\n\r\n"); fileExplain.append("\r\n"); fileDataLength += fileExplain.length(); if(uploadfile.getInStream()!=null){ fileDataLength += uploadfile.getfile().length(); }else{ fileDataLength += uploadfile.getData().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(); 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,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,1024))!=-1){ outStream.write(buffer,len); } uploadfile.getInStream().close(); }else{ outStream.write(uploadfile.getData(),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为参数名,Formfile file) throws Exception{ return post(path,params,new Formfile[]{file}); }}4)、新建MainActivity类,实现每隔5秒上传一次
package com.ljq.activity;import java.io.file;import java.util.HashMap;import java.util.Map;import androID.app.Activity;import androID.os.Bundle;import androID.os.Environment;import androID.os.Handler;import androID.util.Log;import com.ljq.utils.Formfile;import com.ljq.utils.sockethttpRequester;public class MainActivity extends Activity { private file file; private Handler handler; private static final String TAG="MainActivity"; @OverrIDe public voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.main); Log.i(TAG,"onCreate"); file = new file(Environment.getExternalStorageDirectory(),"123.rmvb"); Log.i(TAG,"照片文件是否存在:"+file); handler=new Handler(); handler.post(runnable); } Runnable runnable=new Runnable() { public voID run() { Log.i(TAG,"runnable run"); uploadfile(file); handler.postDelayed(runnable,5000); } }; /** * 上传图片到服务器 * * @param imagefile 包含路径 */ public voID uploadfile(file imagefile) { Log.i(TAG,"upload start"); try { String requestUrl = "http://192.168.1.101:8083/upload/upload/execute.do"; //请求普通信息 Map<String,String> params = new HashMap<String,String>(); params.put("username","张三"); params.put("pwd","zhangsan"); params.put("age","21"); params.put("filename",imagefile.getname()); //上传文件 Formfile formfile = new Formfile(imagefile.getname(),imagefile,"image","application/octet-stream"); SockethttpRequester.post(requestUrl,formfile); Log.i(TAG,"upload success"); } catch (Exception e) { Log.i(TAG,"upload error"); e.printstacktrace(); } Log.i(TAG,"upload end"); }}5)、修改清单文件
<?xml version="1.0" enCoding="utf-8"?><manifest xmlns:androID="http://schemas.androID.com/apk/res/androID" package="com.ljq.activity" androID:versionCode="1" androID:versionname="1.0"> <application androID:icon="@drawable/icon" androID:label="@string/app_name"> <activity androID:name=".MainActivity" androID:label="@string/app_name"> <intent-filter> <action androID:name="androID.intent.action.MAIN" /> <category androID:name="androID.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-sdk androID:minSdkVersion="4" /> <uses-permission androID:name="androID.permission.INTERNET" /> </manifest>
启动模拟器,运行如下:
二、服务器端用来获取AndroID端上传过来的文件信息
1)、新建一个web项目命名为upload,目录结构如下
注意:记得加入struts2 jar包,需加入的jar如下
2)、新建action类,命名为UploadAction,内容如下
package com.ljq.action;import java.io.file;import java.io.fileinputStream;import java.io.fileOutputStream;import java.io.IOException;import javax.servlet.http.httpServletRequest;import org.apache.struts2.ServletActionContext;import com.opensymphony.xwork2.ActionSupport;/** * 获取AndroID端上传过来的信息 * * @author administrator * */@SuppressWarnings("serial")public class UploadAction extends ActionSupport { // 上传文件域 private file image; // 上传文件类型 private String imageContentType; // 封装上传文件名 private String imagefilename; // 接受依赖注入的属性 private String savePath; @OverrIDe public String execute() { httpServletRequest request=ServletActionContext.getRequest(); fileOutputStream fos = null; fileinputStream fis = null; try { System.out.println("获取AndroID端传过来的普通信息:"); System.out.println("用户名:"+request.getParameter("username")); System.out.println("密码:"+request.getParameter("pwd")); System.out.println("年龄:"+request.getParameter("age")); System.out.println("文件名:"+request.getParameter("filename")); System.out.println("获取AndroID端传过来的文件信息:"); System.out.println("文件存放目录: "+getSavePath()); System.out.println("文件名称: "+imagefilename); System.out.println("文件大小: "+image.length()); System.out.println("文件类型: "+imageContentType); fos = new fileOutputStream(getSavePath() + "/" + getimagefilename()); fis = new fileinputStream(getimage()); byte[] buffer = new byte[1024]; int len = 0; while ((len = fis.read(buffer)) != -1) { fos.write(buffer,len); } System.out.println("文件上传成功"); } catch (Exception e) { System.out.println("文件上传失败"); e.printstacktrace(); } finally { close(fos,fis); } return SUCCESS; } /** * 文件存放目录 * * @return */ public String getSavePath() throws Exception{ return ServletActionContext.getServletContext().getRealPath(savePath); } public voID setSavePath(String savePath) { this.savePath = savePath; } public file getimage() { return image; } public voID setimage(file image) { this.image = image; } public String getimageContentType() { return imageContentType; } public voID setimageContentType(String imageContentType) { this.imageContentType = imageContentType; } public String getimagefilename() { return imagefilename; } public voID setimagefilename(String imagefilename) { this.imagefilename = imagefilename; } private voID close(fileOutputStream fos,fileinputStream fis) { if (fis != null) { try { fis.close(); fis=null; } catch (IOException e) { System.out.println("fileinputStream关闭失败"); e.printstacktrace(); } } if (fos != null) { try { fos.close(); fis=null; } catch (IOException e) { System.out.println("fileOutputStream关闭失败"); e.printstacktrace(); } } }}3)、配置struts.xml
<?xml version="1.0" enCoding="UTF-8" ?><!DOCTYPE struts PUBliC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"><struts> <!-- 该属性指定需要Struts2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts2处理。 如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开。 --> <constant name="struts.action.extension" value="do"/> <!-- 设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭 --> <constant name="struts.serve.static.browserCache" value="false"/> <!-- 当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用),开发阶段最好打开 --> <constant name="struts.configuration.xml.reload" value="true"/> <!-- 开发模式下使用,这样可以打印出更详细的错误信息 --> <constant name="struts.devMode" value="true"/> <!-- 默认的视图主题 --> <constant name="struts.ui.theme" value="simple"/> <!--<constant name="struts.objectFactory" value="spring" />--> <!--解决乱码 --> <constant name="struts.i18n.enCoding" value="UTF-8"/> <!-- 指定允许上传的文件最大字节数。默认值是2097152(2M) --> <constant name="struts.multipart.maxSize" value="22097152"/> <!-- 设置上传文件的临时文件夹,默认使用javax.servlet.context.tempdir --> <constant name="struts.multipart.saveDir " value="d:/tmp"/> <package name="upload" namespace="/upload" extends="struts-default"> <action name="execute" > <!-- 动态设置savePath的属性值 --> <param name="savePath">/image</param> <result name="success">/WEB-INF/page/message.Jsp</result> </action> </package></struts>
4)、配置web.xml
<?xml version="1.0" enCoding="UTF-8"?><web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <filter> <filter-name>struts2</filter-name> <filter-class> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter </filter-class> </filter> <filter-mapPing> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapPing> <filter> <filter-name>strutsCleanup</filter-name> <filter-class> org.apache.struts2.dispatcher.ActionContextCleanUp </filter-class> </filter> <filter-mapPing> <filter-name>strutsCleanup</filter-name> <url-pattern>/*</url-pattern> </filter-mapPing> <welcome-file-List> <welcome-file>index.Jsp</welcome-file> </welcome-file-List></web-app>
运行结构如下:
获取AndroID端传过来的普通信息:
用户名:张三
密码:zhangsan
年龄:21
文件名:123.rmvb
获取AndroID端传过来的文件信息:
文件存放目录: D:\apache-tomcat-6.0.18\webapps\upload\image
文件名称: 123.rmvb
文件大小: 3962649
文件类型: application/octet-stream
文件上传成功
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
总结以上是内存溢出为你收集整理的Android实现上传文件到服务器实例详解全部内容,希望文章能够帮你解决Android实现上传文件到服务器实例详解所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)