android上传图片(及普通参数)到服务器(j2ee后台服务器,ssh框架)
2015-10-11 19:43
381 查看
原文地址:http://www.2cto.com/kf/201504/392680.html
android客户端
效果图非常简单:
Android客户端逻辑:
1: 点击选图片—>打开系统的相册选择;
2:点击上传图片,把图片上传到服务器,然后显示进度,以及上传完成后显示服务器返回的json数据。<喎�”http://www.2cto.com/kf/ware/vc/” target=”_blank” class=”keylink”>vcD4NCgk8cD7K18/Iv7S/tM/uxL+1xL3hubk8YnIgLz4NCgk8aW1nIGFsdD0=”这里写图片描述” src=”http://www.2cto.com/uploadfile/Collfiles/20150421/2015042108403722.png” title=”\” />
- 显示的界面在MainAcvtitvity中;
- ConfigParamters是http请求的公共参数配置;
- HttpUrlConn是http请求主要类;
- Uploadllinsener用来监听文件上传的进度,以及上传的状态(成功,失败,进度)。
这里主要是看看HttpUrlConn请求类:
上面的代码是HttpUrlConn的全部代码。
1: getHttpUrlConnInstances()获取并且请求连接服务器;
-方法中主要是获取连接,并且配置连接,然后拼接参数,发送到服务器,然后通过myhttpconnect.getInputStream()获取到服务器返回的数据。
2:InputStremtoString(InputStream)把字节流转换成String;
- 这里主要是为了处理服务器返回的数据。(这里注意编码)
3:writeStringParam(DataOutputStream,HashMap)这个方法主要是为了传输普通的参数;
- 把普通参数装入HashMap中然后循环写出数据,这里的数据是需要拼接的,因为我们提交数据是模拟from表单提交。
4:writeFileParam(DataOutputStream,HashMap)这个方法只要是用来传输文件参数;
- 把需要传输的文件都装在HashMap中,循环遍历hashmap中的文件,一一写到服务器。(在这个方法中获取了所有文件的总大小,用于计算当前的传输进度,还有这里的name和服务器的要一样。)
5:getFilesSize(HashMap)获取文件的总大小;
6:getContentType(File f)获取文件的上传类型,图片格式为image/png,image/jpg等。非图片为application/octet-stream;
7:paramsEnd(DataOutputStream)添加结尾数据;
8:getBytes(File) 把文件转换成字节数组;
9:setUploadlinsener(UploadLinsener)设置传输监听;
这里的核心代码在FileUploadAction中:
这个类是核心业务类,当客户端发送请求是进入到这个方法中,并且获取到参数数据。
在服务端有两种方式能后获取到android的普通参数,
一是通过HttpServletRequest的getParameter(arg0)方法来获取;
二是从提交的表单中获取:
经过测试传输速度的确挺快的5MB的图片几秒钟就能传输完成,注意这里如果是在android客户端模拟机中调试程序,那里的请求地址中的ip应该为10.0.0.2:8080…..否则找不到服务器,如果是真机上测试可以直接发布到你电脑的tomcat中,然后把ip改成你点击的ip就可以了(这里电脑和android手机需要连接到同一个网络wifi,也就是内网,当然也可以拿到公司的服务器上测试)。
项目测试通过,效果也挺好的,不过这里还有一个问题没解决,就是通过from表单提交上来的普通参数如果是中文这里好像还是会乱码。
最近项目中需要客户端往服务器传输图片,并且还需要附带一些普通参数,研究了几天,把结果记录下。 首先客户端可服务端进行通信一般都是有http请求来发送和接收数据,这里android中有两种HttpClient和HttpURLConnection,这两个都可以和后台服务器进行网络通信,但是如何选择哪个来进行文件传输呢? 谷歌官方是提倡我们使用HttpURLConnection来和服务器进行通信(这个是在android.jar中就有),HttpClient这个是org.apache.http.client.HttpClient下的一个工具类,根据网上的一些测试,得出的一些理论结果是使用HttpURLConnection来传输文件比HttpClient要快一些,在普通参数传输上都差不多。 既然谷歌推荐,所以我么这里就选择HttpURLConnection来实现传输文件。
android客户端
效果图非常简单:
Android客户端逻辑:
1: 点击选图片—>打开系统的相册选择;
2:点击上传图片,把图片上传到服务器,然后显示进度,以及上传完成后显示服务器返回的json数据。<喎�”http://www.2cto.com/kf/ware/vc/” target=”_blank” class=”keylink”>vcD4NCgk8cD7K18/Iv7S/tM/uxL+1xL3hubk8YnIgLz4NCgk8aW1nIGFsdD0=”这里写图片描述” src=”http://www.2cto.com/uploadfile/Collfiles/20150421/2015042108403722.png” title=”\” />
- 显示的界面在MainAcvtitvity中;
- ConfigParamters是http请求的公共参数配置;
- HttpUrlConn是http请求主要类;
- Uploadllinsener用来监听文件上传的进度,以及上传的状态(成功,失败,进度)。
这里主要是看看HttpUrlConn请求类:
public class HttpUrlConn { //标签 private String TAG=HttpUrlConn; //HttpURLConnection请求 private HttpURLConnection myhttpconnect; //结束点 private String end = ; //分割标记twoHyphens private String twoHyphens = --; //分割标记 private String boundary = *****; //数据输出管道 private DataOutputStream ds=null; //文件上传监听 private UploadLinsener uploadlinsener; //文件总大小 private double allFilesize=0; //当前传输了多少 private double curr_ret=0; /** * HttpURLConnection连接服务器请求 * @param path :接口地址 * @param param1 :普通参数 * @param paramFiles:需要上传的文件参数 * @param config:连接公共属性配置 * @return */ public HttpURLConnection getHttpUrlConnInstances(String path, HashMap<string, string=""> paramString, HashMap<string, file=""> paramFiles, ConfigParamters config){ try { //这里可以放普通参数,(第一种方法) // StringBuffer sb=new StringBuffer(path); // if(null!=paramString&¶mString.size()>0){ // sb.append(?); // for(Entry<string, string=""> data:paramString.entrySet()){ // sb.append(data.getKey()+=+data.getValue()); // sb.append(&); // } // } // path=sb.substring(0, sb.lastIndexOf(&)); URL url=new URL(path); myhttpconnect=(HttpURLConnection) url.openConnection(); /* 允许Input、Output,post中不使用Cache */ myhttpconnect.setDoInput(config.isDoInput()); myhttpconnect.setDoOutput(config.isDoOutput()); myhttpconnect.setUseCaches(config.isUseCaches()); /* 设置传送的method=POST */ myhttpconnect. setRequestMethod(config.getUseMethod()); /*设置属性 setRequestProperty */ myhttpconnect .setRequestProperty(Connection, Keep-Alive); myhttpconnect.setRequestProperty(Charset, UTF-8); myhttpconnect.setRequestProperty(Content-Type, multipart/form-data;boundary= + boundary); /* 设置DataOutputStream */ ds = new DataOutputStream( myhttpconnect.getOutputStream()); /*把普通参数写到服务器*/ if(null!=paramString&¶mString.size()>0){ writeStringParam(ds, paramString); } /*把文件参数写到服务器*/ if(null!=paramFiles&¶mFiles.size()>0){ writeFileParam(ds, paramFiles); } //添加结尾标志 paramsEnd(ds); if(myhttpconnect.getResponseCode() ==HttpURLConnection.HTTP_OK){ InputStream is = myhttpconnect.getInputStream(); String successMsg=InputStremtoString(is); //成功 if(uploadlinsener!=null){ uploadlinsener.uploadSucsess(successMsg); } }else{ uploadlinsener.uploadFail(错误,错误码 ResponseCode:+ myhttpconnect.getResponseCode()); } ds.close(); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); if(uploadlinsener!=null){ uploadlinsener.uploadFail(e.toString()); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); if(uploadlinsener!=null){ uploadlinsener.uploadFail(e.toString()); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); if(uploadlinsener!=null){ uploadlinsener.uploadFail(e.toString()); } } return myhttpconnect; } /** * 把字节输入流转换成字符串 * @return */ private String InputStremtoString(InputStream is)throws Exception{ int ch; StringBuffer b = new StringBuffer(); byte[] bt=new byte[1024]; while ((ch = is.read(bt)) != -1) { b.append(new String(bt, 0, ch, UTF-8)); } return b.toString(); } /** * 传普通参数(第二种方法) * @param parm:参数 */ private void writeStringParam(DataOutputStream ds, HashMap<string, string=""> params){ try{ Set<string> keySet = params.keySet(); for (Iterator<string> it =keySet.iterator(); it.hasNext();){ String name = it.next(); String value = params.get(name); ds.writeBytes(twoHyphens + boundary + end); ds.writeBytes(Content-Disposition: form-data; name= + name ++ end); ds.writeBytes(end); //URLEncoder.encode(value) ds.writeBytes(new String(value.getBytes(),UTF-8)+ end); } }catch(Exception e){ e.printStackTrace(); } } /*** * 传输文件 * @param ds :数据传输通道 * @param params :参数 */ private void writeFileParam(DataOutputStream ds,HashMap<string, file=""> params){ try{ Set<string> keySet = params.keySet(); getFilesSize(params); for (Iterator<string> it =keySet.iterator(); it.hasNext();){ String name = it.next(); File value = params.get(name); ds.writeBytes(twoHyphens + boundary + end); ds.writeBytes(Content-Disposition: form-data; name= + name + ; filename= + URLEncoder.encode(value.getName()) + +end); ds.writeBytes(Content-Type: + getContentType(value) + end); ds.writeBytes(end); ds.write(getBytes(value)); ds.writeBytes(end); } }catch(Exception e){ e.printStackTrace(); } } /** * 获取要传输文件总共大小 * @param params */ private void getFilesSize(HashMap<string, file=""> params){ for(Entry<string, file=""> data:params.entrySet()){ File f=data.getValue(); allFilesize+=f.length(); } Log.i(TAG, AllFileSize:+allFilesize); } /** * 获取文件的上传类型,图片格式为image/png,image/jpg等。非图片为application/octet-stream * @param f 文件 * @return * @throws Exception */ private String getContentType(File f) throws Exception{ return application/octet-stream; } /** * 添加结尾数据 * @param ds:数据传输通道 * * @throws Exception */ private void paramsEnd( DataOutputStream ds) throws Exception { ds.writeBytes(twoHyphens + boundary + twoHyphens + end); ds.writeBytes(end); } /** * 把文件转换成字节数组 * @param f:文件 * @return * @throws Exception */ private byte[] getBytes(File f) throws Exception{ FileInputStream in = new FileInputStream(f); ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] b = new byte[1024]; int n; while ((n = in.read(b)) != -1) { out.write(b, 0, n); if(allFilesize>0){ curr_ret+=n; double level=(curr_ret/allFilesize)*100; Log.i(result, +level); if(uploadlinsener!=null){ uploadlinsener.uploading(level); } } } in.close(); return out.toByteArray(); } public void setUploadlinsener(UploadLinsener uploadlinsener) { this.uploadlinsener = uploadlinsener; } }
上面的代码是HttpUrlConn的全部代码。
1: getHttpUrlConnInstances()获取并且请求连接服务器;
-方法中主要是获取连接,并且配置连接,然后拼接参数,发送到服务器,然后通过myhttpconnect.getInputStream()获取到服务器返回的数据。
2:InputStremtoString(InputStream)把字节流转换成String;
- 这里主要是为了处理服务器返回的数据。(这里注意编码)
3:writeStringParam(DataOutputStream,HashMap)这个方法主要是为了传输普通的参数;
- 把普通参数装入HashMap中然后循环写出数据,这里的数据是需要拼接的,因为我们提交数据是模拟from表单提交。
4:writeFileParam(DataOutputStream,HashMap)这个方法只要是用来传输文件参数;
- 把需要传输的文件都装在HashMap中,循环遍历hashmap中的文件,一一写到服务器。(在这个方法中获取了所有文件的总大小,用于计算当前的传输进度,还有这里的name和服务器的要一样。)
5:getFilesSize(HashMap)获取文件的总大小;
6:getContentType(File f)获取文件的上传类型,图片格式为image/png,image/jpg等。非图片为application/octet-stream;
7:paramsEnd(DataOutputStream)添加结尾数据;
8:getBytes(File) 把文件转换成字节数组;
9:setUploadlinsener(UploadLinsener)设置传输监听;
这里的核心代码在FileUploadAction中:
public class FileUploadAction extends ActionSupport{ public String phoneinfo=NXJ570; public void uploadfielandparam() throws Exception{ System.out.println(upload); HttpServletRequest request= ServletActionContext.getRequest(); System.out.println(request.getContentType()); System.out.println(request.getCharacterEncoding()); System.out.println(request.getContentLength()); //临时文件夹,在tomcat项目下的temp String temp = ServletActionContext .getServletContext() .getRealPath()+ \temp; System.out.println(temp); //上传文件存放地方 String basepath=ServletActionContext .getServletContext() .getRealPath()+\myfile; //获取Response HttpServletResponse resp= ServletActionContext.getResponse(); DiskFileItemFactory factory = new DiskFileItemFactory(); //单个文件缓存最大值 factory.setSizeThreshold(10 * 1024 * 1024); // 缓冲区 factory.setRepository(new File(temp)); //文件上传组件(关键) ServletFileUpload upload1= new ServletFileUpload(factory); upload1.setFileSizeMax(10000000); upload1.setSizeMax(480000000); upload1.setHeaderEncoding(UTF-8); // 设置一旦文件大小超过getSizeThreshold() //的值时数据存放在硬盘的目录 // 开始读取上传信息 int index = 0; List fileItems= null; try { fileItems=upload1.parseRequest(request); System.out.println(list= + fileItems); } catch (Exception e) { e.printStackTrace(); } Iterator iter = fileItems.iterator(); // 依次处理每个上传的文件 while (iter.hasNext()) { FileItem item = (FileItem) iter.next(); // 忽略其他不是文件域的所有表单信息 if (!item.isFormField()) { String name = item.getName(); // 获取上传文件名,包括路径 name = name.substring( name.lastIndexOf(\) + 1); // 从全路径中提取文件名 long size = item.getSize(); if ((name == null || name.equals()) && size == 0) continue; int point = name.indexOf(.); name = (new Date()).getTime() + name.substring(point, name.length()); System.out.println(fileName=+name); index++; File fNew = new File(basepath, name); try { item.write(fNew); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } else // 取出不是文件域的所有表单信息 { //如果包含中文应写为:(转为UTF-8编码) String key=item.getFieldName(); String fieldvalue = .getBytes(),UTF-8);//UTF-8 System.out .println( params:+key+=+fieldvalue); } } //把对象转换成json Gson gson = new Gson(); myobj obj1=new myobj(0, seccessed, 服务器已经接收到文件); String json = gson.toJson(obj1); System.out.println(json); //设置格式(必须设置,否则客户端接收到的json中文乱码) resp.setContentType(text/html; charset=utf-8); PrintWriter out = resp.getWriter(); out.println(json); out.flush(); } //实体对象 class myobj{ private String retcode; private String retmessage; private String retdata; public myobj(String retcode, String retmessage, String retdata) { super(); this.retcode = retcode; this.retmessage = retmessage; this.retdata = retdata; } public String getRetcode() { return retcode; } public void setRetcode(String retcode) { this.retcode = retcode; } public String getRetmessage() { return retmessage; } public void setRetmessage(String retmessage) { this.retmessage = retmessage; } public String getRetdata() { return retdata; } public void setRetdata(String retdata) { this.retdata = retdata; } }
这个类是核心业务类,当客户端发送请求是进入到这个方法中,并且获取到参数数据。
在服务端有两种方式能后获取到android的普通参数,
一是通过HttpServletRequest的getParameter(arg0)方法来获取;
二是从提交的表单中获取:
String key=item.getFieldName(); //获取vaule String fieldvalue =new String(item.getString().getBytes(),UTF-8);
经过测试传输速度的确挺快的5MB的图片几秒钟就能传输完成,注意这里如果是在android客户端模拟机中调试程序,那里的请求地址中的ip应该为10.0.0.2:8080…..否则找不到服务器,如果是真机上测试可以直接发布到你电脑的tomcat中,然后把ip改成你点击的ip就可以了(这里电脑和android手机需要连接到同一个网络wifi,也就是内网,当然也可以拿到公司的服务器上测试)。
项目测试通过,效果也挺好的,不过这里还有一个问题没解决,就是通过from表单提交上来的普通参数如果是中文这里好像还是会乱码。
相关文章推荐
- Android 获取手机的联系人进行操作
- Android 操作软键盘
- Android 容器焦点设置 android:descendantFocusability
- Android数据存储方式之——Shareprefences
- Android按钮跳转页面
- Android Design ItemTouchHelper实现酷炫列表的移行和滑动删除效果
- Android中使用pull解析xml文件
- Android NotificationManager的简单使用
- Android客户端与PC服务器如何实现Socket通信
- Android获取到inflate服务的方式及inflate的解析过程
- Android Paint和Color类介绍
- Android杂谈--ListView之BaseAdapter的使用
- 五步搞定Android开发环境部署——非常详细的Android开发环境搭建教程
- Android launcher开发介绍
- Android RecyclerView相关简化
- 一些使用Android设备调试功能的注意事项(挖职位)
- Android仿百度加载动画
- android【基础】 style标签应用与activity间的淡入淡出切换
- Android每日范例——TextView文字内容更改
- Android每日范例——背景修改