bug修改之后的代码:
import java.io.BufferedInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.util.HashMap; import java.util.Map; import java.util.Timer; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import com.lubansoft.test.upload.po.UploadRecord; import com.lubansoft.test.upload.po.UploadResult; public class FileUpload { /** * 接收上传的参数和文件 */ public UploadResult upload(HttpServletRequest request,HttpServletResponse response){ UploadResult uploadResult = new UploadResult(); try { InputStream in = new BufferedInputStream(request.getInputStream(),10240); String requestHeader = readLine(in); String line = null; Map<String,String> param = new HashMap<String, String>(); Map<String,String> fileUploadResults = new HashMap<String, String>(); uploadResult.setParams(param); uploadResult.setFileUploadResults(fileUploadResults); /** * 判断是否是文件/参数 */ if("------parameters------".equals(requestHeader)){ /** * 上传参数的格式: * 第一行: ------parameters------ * 第二行:"parameterLength=" + parameterLength * 第三行: key1=value1&key2=value2........ */ line = readLine(in); int length = 0; if(line != null){ if("parameterLength".equals(line.split("=")[0])){ length = Integer.parseInt(line.split("=")[1]); } } byte[] b = null; if(length != 0){ b = new byte[length]; in.read(b, 0, length); line = new String(b,0,length,"utf-8"); } if(line != null){ String[] params = line.split("&"); if(params!=null && params.length>0){ for(String keyValue : params){ param.put(keyValue.split("=")[0], keyValue.split("=")[1]); } } } System.out.println(param); /** *读取最后的一个换行符:\n */ readLine(in); if("------file begin------".equals(line=readLine(in))){ startTimerAndUploadFile(request, in, fileUploadResults); } }else if("------file begin------".equals(requestHeader)){ startTimerAndUploadFile(request, in, fileUploadResults); } } catch (Exception e) { e.printStackTrace(); } finally { try { response.getWriter().write("upload complete !"); } catch (IOException e) { e.printStackTrace(); } } return uploadResult; } /** * 启动定时器,开始上传文件 */ public void startTimerAndUploadFile(HttpServletRequest request,InputStream in,Map<String,String> fileUploadResults){ Timer timer = new Timer(); UploadRateTimerTask task = new UploadRateTimerTask(request); long interval = FileUploadUtil.getTimerInfo(request) != null ? Long.parseLong(FileUploadUtil.getTimerInfo(request)[0]) : 1000; timer.schedule(task, 0 , interval); saveFile(in, request, task,fileUploadResults); timer.cancel(); } //保存文件 public void saveFile(InputStream in ,HttpServletRequest request,UploadRateTimerTask task,Map<String,String> fileUploadResults){ String line=null; RandomAccessFile raf = null; UploadRecord uploadRecord = null; String fileMD5_client = null; String fileMD5_server = null; int blockSize = FileUploadUtil.getBlockSize(); try { task.setTotal_uploadSize(0); //先读到该文件的信息头“fileName=ddd&fileSize=xxx&uploadSize=aaa” line = readLine(in); if(line != null){ uploadRecord = FileUploadUtil.getUploadRecoreFromString(line); fileMD5_client = uploadRecord.getFileMD5(); HttpSession session = request.getSession(); String folder = session.getServletContext().getRealPath(UploadConfigConstants.UPLOAD_FILE); String filepath = folder+File.separator + FileUploadUtil.getFileNameByUploadRecord(uploadRecord); File file = new File(filepath); if(! file.getParentFile().exists()){ file.getParentFile().mkdirs(); } if(! file.exists()){ file.createNewFile(); } /** * 先将properties文件放到临时文件夹下(tmep) */ String config_path = session.getServletContext().getRealPath(UploadConfigConstants.BREAK_POINT) + File.separator + "temp/" + FileUploadUtil.getConfigFileNameByUploadRecord(uploadRecord); File config_file = new File(config_path); if(! config_file.getParentFile().exists()){ config_file.getParentFile().mkdirs(); } if (! config_file.exists()) { config_file.createNewFile(); } raf = new RandomAccessFile(file, "rwd"); raf.setLength(uploadRecord.getFileSize()); //将读取文件的指针移动到断点位置 raf.seek(uploadRecord.getUploadSize()); //计算出从断点位置到文件结尾,还剩下的文件大小 long leftSize = uploadRecord.getFileSize()-uploadRecord.getUploadSize(); //本次上传,上传完成的文件大小 long completeSize = 0l; /** * 接下来是文件的内容 */ int n=-1; byte[] b = new byte[2048]; int addSize = 0; /** * 在上传文件的时候,再去判断一下是否已经有程序在上传该文件 * 作为确认,防止万一 */ boolean isStarted = false; if(FileUploadUtil.isUploadStarted(request, uploadRecord)){ isStarted = true; } /** * 为定时器动态绑定uploadRecord对象 */ task.setUploadRecord(uploadRecord); /** * 判断文件从断点开始,还有多大文件需要传输,如果太小(小于 1 k )就要特殊处理 * 因为这时候不能使用 in.read(b) ,而只能使用 in.read(b,0,leftSize) */ if((completeSize + b.length) <= leftSize){ while((n=in.read(b)) != -1){ if(! isStarted){ raf.write(b,0,n); completeSize += n; addSize += n; task.setTotal_uploadSize(completeSize); if(addSize >= blockSize){ FileUploadUtil.updateUploadSize(request, uploadRecord, addSize); addSize = 0; } } /** * 最后一部分特殊处理 */ if((completeSize + b.length) >= leftSize){ int num = -1; while(true){ /** * num表示最后一部分还剩下多少,也就是应该读取的大小 * n表示真正读取到的部分是多少,也就是实际上读取到的大小 * n和num可能并不相同,一直到leftSize == completeSize才说明最后一部分处理完成 */ num = (int)(leftSize-completeSize); n = in.read(b, 0, num); completeSize += n; if(! isStarted){ raf.write(b,0,n); addSize += n; task.setTotal_uploadSize(completeSize); if(addSize >= blockSize){ FileUploadUtil.updateUploadSize(request, uploadRecord, addSize); addSize = 0; } } /** * 如果leftSize == completeSize说明最后一部分处理完成 */ if(leftSize == completeSize){ raf.close(); FileUploadUtil.updateUploadSize(request, uploadRecord, addSize); addSize = 0; //完成一个文件的上传,将该文件的完成百分比改为100% task.setTaskComplete(); //完成一个文件的上传,将该文件的isStopped改为stopped FileUploadUtil.setConfigFileStoped(request, uploadRecord); fileMD5_server = MD5Util.getFileMD5String(file); if(fileMD5_server != null && fileMD5_client != null){ if(fileMD5_server.equals(fileMD5_client)){ fileUploadResults.put(file.getName(), "OK"); /** * 文件上传完成并且校验成功,则将其配置文件转移到已上传成功的文件夹 */ FileUploadUtil.MoveFile(config_file, session.getServletContext().getRealPath(UploadConfigConstants.BREAK_POINT)); } }else{ /** * 文件上传完成,但是文件已损坏 */ fileUploadResults.put(file.getName(), "DAMAGED"); } readLine(in); line = readLine(in); if("------file begin------".equals(line)){ saveFile(in, request,task,fileUploadResults); } break; } } } } }else{//判断文件从断点开始,如果剩余文件太小(小于 1 k )就要特殊处理 int num = -1; while(true){ num = (int)(leftSize-completeSize); n = in.read(b, 0, num); completeSize += n; if(! isStarted){ raf.write(b,0,n); addSize += n; task.setTotal_uploadSize(completeSize); if(addSize >= blockSize){ FileUploadUtil.updateUploadSize(request, uploadRecord, addSize); addSize = 0; } } if(leftSize == completeSize){ raf.close(); FileUploadUtil.updateUploadSize(request, uploadRecord, addSize); addSize = 0; //完成一个文件的上传,将该文件的完成百分比改为100% task.setTaskComplete(); //完成一个文件的上传,将该文件的isStopped改为stopped FileUploadUtil.setConfigFileStoped(request, uploadRecord); fileMD5_server = MD5Util.getFileMD5String(file); if(fileMD5_server != null && fileMD5_client != null){ if(fileMD5_server.equals(fileMD5_client)){ fileUploadResults.put(file.getName(), "OK"); /** * 文件上传完成并且校验成功,则将其配置文件转移到已上传成功的文件夹 */ FileUploadUtil.MoveFile(config_file, session.getServletContext().getRealPath(UploadConfigConstants.BREAK_POINT)); } }else{ /** * 文件上传完成,但是文件已损坏 */ fileUploadResults.put(file.getName(), "DAMAGED"); } readLine(in); line = readLine(in); if("------file begin------".equals(line)){ saveFile(in, request,task,fileUploadResults); } break; } } } /** * 文件上传完成,将状态修改为 “stoped” */ if(uploadRecord != null){ FileUploadUtil.setConfigFileStoped(request, uploadRecord); } } // } } catch (IOException e) { /** * 上传过程中出现异常,将状态修改为 “stoped” */ e.printStackTrace(); }finally{ /** * 上传过程中出现异常,将状态修改为 “stoped” */ if(uploadRecord != null){ FileUploadUtil.setConfigFileStoped(request, uploadRecord); } if(raf != null){ try { raf.close(); } catch (IOException e1) { e1.printStackTrace(); } raf = null; } } } /** * 读取一行内容 */ private String readLine(InputStream in) { return FileUploadUtil.readLine(in); } }
之前的代码:
import java.io.BufferedInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.util.HashMap; import java.util.Map; import java.util.Timer; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import com.lubansoft.test.upload.po.UploadRecord; import com.lubansoft.test.upload.po.UploadResult; public class FileUpload { /** * 接收上传的参数和文件 */ public UploadResult upload(HttpServletRequest request,HttpServletResponse response){ UploadResult uploadResult = new UploadResult(); try { InputStream in = new BufferedInputStream(request.getInputStream(),10240); String requestHeader = readLine(in); String line = null; Map<String,String> param = new HashMap<String, String>(); Map<String,String> fileUploadResults = new HashMap<String, String>(); uploadResult.setParams(param); uploadResult.setFileUploadResults(fileUploadResults); /** * 判断是否是文件/参数 */ if("------parameters------".equals(requestHeader)){ /** * 上传参数的格式: * 第一行: ------parameters------ * 第二行:"parameterLength=" + parameterLength * 第三行: key1=value1&key2=value2........ */ line = readLine(in); int length = 0; if(line != null){ if("parameterLength".equals(line.split("=")[0])){ length = Integer.parseInt(line.split("=")[1]); } } byte[] b = null; if(length != 0){ b = new byte[length]; in.read(b, 0, length); line = new String(b,0,length,"utf-8"); } if(line != null){ String[] params = line.split("&"); if(params!=null && params.length>0){ for(String keyValue : params){ param.put(keyValue.split("=")[0], keyValue.split("=")[1]); } } } System.out.println(param); /** *读取最后的一个换行符:\n */ readLine(in); if("------file begin------".equals(line=readLine(in))){ startTimerAndUploadFile(request, in, fileUploadResults); } }else if("------file begin------".equals(requestHeader)){ startTimerAndUploadFile(request, in, fileUploadResults); } } catch (Exception e) { e.printStackTrace(); } finally { try { response.getWriter().write("upload complete !"); } catch (IOException e) { e.printStackTrace(); } } return uploadResult; } /** * 启动定时器,开始上传文件 */ public void startTimerAndUploadFile(HttpServletRequest request,InputStream in,Map<String,String> fileUploadResults){ Timer timer = new Timer(); UploadRateTimerTask task = new UploadRateTimerTask(request); long interval = FileUploadUtil.getTimerInfo(request) != null ? Long.parseLong(FileUploadUtil.getTimerInfo(request)[0]) : 1000; timer.schedule(task, 0 , interval); saveFile(in, request, task,fileUploadResults); timer.cancel(); } //保存文件 public void saveFile(InputStream in ,HttpServletRequest request,UploadRateTimerTask task,Map<String,String> fileUploadResults){ String line=null; // String fileName=null; // String fileSize = null; // String uploadSize=null; RandomAccessFile raf = null; UploadRecord uploadRecord = null; String fileMD5_client = null; String fileMD5_server = null; int blockSize = FileUploadUtil.getBlockSize(); try { task.setTotal_uploadSize(0); //先读到该文件的信息头“fileName=ddd&fileSize=xxx&uploadSize=aaa” line = readLine(in); if(line != null){ /*String[] info = line.split("&"); if(info != null && info.length>0){ for(String s: info){ if("fileName".equals(s.split("=")[0])){ fileName = s.split("=")[1]; }else if("fileSize".equals(s.split("=")[0])){ fileSize = s.split("=")[1]; }else if("uploadSize".equals(s.split("=")[0])){ uploadSize = s.split("=")[1]; }else if("fileMD5".equals(s.split("=")[0])){ fileMD5_client = s.split("=")[1]; } }*/ uploadRecord = FileUploadUtil.getUploadRecoreFromString(line); fileMD5_client = uploadRecord.getFileMD5(); HttpSession session = request.getSession(); String folder = session.getServletContext().getRealPath(UploadConfigConstants.UPLOAD_FILE); String filepath = folder+File.separator + FileUploadUtil.getFileNameByUploadRecord(uploadRecord); File file = new File(filepath); if(! file.getParentFile().exists()){ file.getParentFile().mkdirs(); } if(! file.exists()){ file.createNewFile(); } /** * 先将properties文件放到临时文件夹下(tmep) */ String config_path = session.getServletContext().getRealPath(UploadConfigConstants.BREAK_POINT) + File.separator + "temp/" + FileUploadUtil.getConfigFileNameByUploadRecord(uploadRecord); File config_file = new File(config_path); if(! config_file.getParentFile().exists()){ config_file.getParentFile().mkdirs(); } if (! config_file.exists()) { config_file.createNewFile(); } raf = new RandomAccessFile(file, "rwd"); // if(file.length() != Long.parseLong(fileSize)){ // raf.setLength(Long.parseLong(fileSize)); // } raf.setLength(uploadRecord.getFileSize()); //将读取文件的指针移动到断点位置 raf.seek(uploadRecord.getUploadSize()); //计算出从断点位置到文件结尾,还剩下的文件大小 long leftSize = uploadRecord.getFileSize()-uploadRecord.getUploadSize(); //本次上传,上传完成的文件大小 long completeSize = 0l; /** * 接下来是文件的内容 */ int n=-1; byte[] b = new byte[2048]; int total = 0; int addSize = 0; /*uploadRecord = new UploadRecord(); uploadRecord.setFileName(uploadRecord.getFileName()); uploadRecord.setFileSize(uploadRecord.getFileSize()); uploadRecord.setIp(request.getRemoteAddr()); uploadRecord.setUploadSize(Long.parseLong(uploadSize));*/ /** * 在上传文件的时候,再去判断一下是否已经有程序在上传该文件 * 作为确认,防止万一 */ boolean isStarted = false; if(FileUploadUtil.isUploadStarted(request, uploadRecord)){ isStarted = true; } /** * 为定时器动态绑定uploadRecord对象 */ task.setUploadRecord(uploadRecord); /** * 判断文件从断点开始,还有多大文件需要传输,如果太小(小于 1 k )就要特殊处理 * 因为这时候不能使用 in.read(b) ,而只能使用 in.read(b,0,leftSize) */ if((completeSize + b.length) <= leftSize){ while((n=in.read(b)) != -1){ if(! isStarted){ raf.write(b,0,n); total += n; completeSize += n; addSize += n; task.setTotal_uploadSize(completeSize); if(addSize >= blockSize){ FileUploadUtil.updateUploadSize(request, uploadRecord, addSize); addSize = 0; } } //判断是否已经到达最后一部分 if((completeSize + b.length) >= leftSize){ n = (int)(leftSize-completeSize); 问题就出在这里,因为客户端使用的是conn.setChunkedStreamingMode(10*1024);也就是块的概念,每次传输给服务器10*1024大小的内容,那么就可能会出现一个文件的最后一部分,被分在了两块里面,也就是分两次上传,这种情况下,in.read(b,0,n)就不能读取到n个字节的内容,而是少于n个,因此,这里需要获取到真正读取到的字节数:realNum = in.read(b, 0, n);然后判断(n-realNum)的大小,如果大于0,说明还没有读取完成,就需要循环,所以正确的方式应该如下: /** * 最后一部分特殊处理 */ if((completeSize + b.length) >= leftSize){ int num = -1; while(true){ /** * num表示最后一部分还剩下多少 * n表示真正读取到的部分是多少 * n和num可能并不相同 */ num = (int)(leftSize-completeSize); n = in.read(b, 0, num); completeSize += n; if(! isStarted){ raf.write(b,0,n); addSize += n; task.setTotal_uploadSize(completeSize); if(addSize >= blockSize){ FileUploadUtil.updateUploadSize(request, uploadRecord, addSize); addSize = 0; } } /** * 如果leftSize == completeSize说明最后一部分处理完成 */ if(leftSize == completeSize){ raf.close(); FileUploadUtil.updateUploadSize(request, uploadRecord, addSize); addSize = 0; //完成一个文件的上传,将该文件的完成百分比改为100% task.setTaskComplete(); //完成一个文件的上传,将该文件的isStopped改为stopped FileUploadUtil.setConfigFileStoped(request, uploadRecord); fileMD5_server = MD5Util.getFileMD5String(file); if(fileMD5_server != null && fileMD5_client != null){ if(fileMD5_server.equals(fileMD5_client)){ fileUploadResults.put(file.getName(), "OK"); /** * 文件上传完成并且校验成功,则将其配置文件转移到已上传成功的文件夹 */ FileUploadUtil.MoveFile(config_file, session.getServletContext().getRealPath(UploadConfigConstants.BREAK_POINT)); } }else{ /** * 文件上传完成,但是文件已损坏 */ fileUploadResults.put(file.getName(), "DAMAGED"); } readLine(in); line = readLine(in); if("------file begin------".equals(line)){ saveFile(in, request,task,fileUploadResults); } break; } } } 而不是: in.read(b, 0, n); if(! isStarted){ raf.write(b,0,n); total += n; completeSize += n; addSize += n; raf.close(); task.setTotal_uploadSize(completeSize); FileUploadUtil.updateUploadSize(request, uploadRecord, addSize); addSize = 0; //完成一个文件的上传,将该文件的完成百分比改为100% task.setTaskComplete(); //完成一个文件的上传,将该文件的isStopped改为stopped FileUploadUtil.setConfigFileStoped(request, uploadRecord); fileMD5_server = MD5Util.getFileMD5String(file); if(fileMD5_server != null && fileMD5_client != null){ if(fileMD5_server.equals(fileMD5_client)){ fileUploadResults.put(file.getName(), "OK"); /** * 文件上传完成并且校验成功,则将其配置文件转移到已上传成功的文件夹 */ FileUploadUtil.MoveFile(config_file, session.getServletContext().getRealPath(UploadConfigConstants.BREAK_POINT)); } }else{ /** * 文件上传完成,但是文件已损坏 */ fileUploadResults.put(file.getName(), "DAMAGED"); } file = null; } readLine(in); line = readLine(in); if("------file begin------".equals(line)){ saveFile(in, request,task,fileUploadResults); } break; } } System.out.println(completeSize); }else{//判断文件从断点开始,如果剩余文件太小(小于 1 k )就要特殊处理 in.read(b, 0, (int)leftSize); if(!isStarted){ raf.write(b, 0, (int)leftSize); } raf.close(); task.setTotal_uploadSize(leftSize); FileUploadUtil.updateUploadSize(request, uploadRecord, leftSize); //完成一个文件的上传,将该文件的完成百分比改为100% task.setTaskComplete(); //完成一个文件的上传,将该文件的isStopped改为stopped FileUploadUtil.setConfigFileStoped(request, uploadRecord); readLine(in); line = readLine(in); if("--file begin--".equals(line)){ saveFile(in, request,task,fileUploadResults); fileMD5_server = MD5Util.getFileMD5String(file); if(fileMD5_server != null && fileMD5_client != null){ if(fileMD5_server.equals(fileMD5_client)){ fileUploadResults.put(file.getName(), "OK"); } }else{ fileUploadResults.put(file.getName(), "DAMAGED"); } }else if("------complete------".equals(line)){ in.close(); in = null; System.out.println("------complete------"); } } /** * 文件上传完成,将状态修改为 “stoped” */ if(uploadRecord != null){ FileUploadUtil.setConfigFileStoped(request, uploadRecord); } } // } } catch (IOException e) { /** * 上传过程中出现异常,将状态修改为 “stoped” */ e.printStackTrace(); }finally{ /** * 上传过程中出现异常,将状态修改为 “stoped” */ if(uploadRecord != null){ FileUploadUtil.setConfigFileStoped(request, uploadRecord); } if(raf != null){ try { raf.close(); } catch (IOException e1) { e1.printStackTrace(); } raf = null; } } } /** * 读取一行内容 */ private String readLine(InputStream in) { return FileUploadUtil.readLine(in); } }
这个问题的解决让我进一步明白,出现问题的时候,尽量从自己身上找问题,这才是正道
相关推荐
正文:我在使用HttpURLConnection.getResponseCode()的时候直接报错是IOException错误,responseCode = -1。一直想不明白,同一个程序我调用了两次,结果有一个链接一直OK,另一个却一直报这个错误。后来发现两个...
本篇文章将详细讲解如何使用`HttpURLConnection`实现文件上传,同时涉及到服务器端处理上传文件的代码。我们将讨论以下核心知识点: 1. **HttpURLConnection介绍**: `HttpURLConnection`是Java标准库中的类,它是...
在Android开发中,有时我们需要将本地的文件上传到服务器,以实现数据的同步或备份功能。本示例重点讲解如何利用Java内置的HttpURLConnection类来完成这个任务。HttpURLConnection是Java标准库提供的一种轻量级的...
【多线程上传和下载使用HttpURLConnection】 在Java中,HttpURLConnection是用于处理HTTP协议的基础类,它提供了发送HTTP请求和接收HTTP响应的功能。在本文中,我们将详细讨论如何使用HttpURLConnection实现多线程...
【多线程上传和下载HttpURLConnection】的知识点详解 在Java编程中,`HttpURLConnection`是用于处理HTTP连接的基础类,它可以用来实现文件的上传和下载。本篇内容主要涉及如何利用`HttpURLConnection`实现多线程...
JAVA通过HttpURLConnection上传和下载文件的方法 JAVA通过HttpURLConnection上传和下载文件的方法是非常有实用价值的,需要的朋友可以参考下。HttpURLConnection是一个Java类,用于从网络中读取数据或向网络中写入...
本知识点将深入探讨如何使用`HttpURLConnection`与Servlet协同工作,处理多文件参数以及实现断点上传功能。 首先,`HttpURLConnection`是Java API中的一个核心类,它负责提供HTTP协议的连接功能。相比Apache ...
在Java开发中,HttpURLConnection是替代过时的HttpURLConnection API(即HttpClient)的一个选择,它提供了更现代的API和更好的性能优化。 HttpURLConnection类是Java.net包下的一个核心类,它实现了对HTTP协议的...
在本例中,我们将探讨如何使用`HttpURLConnection`来下载图片,这是一个基础但实用的网络编程任务。下面我们将详细介绍这个过程,并涉及到的相关知识点。 1. **HttpURLConnection简介**: `HttpURLConnection`是`...
在本文中,我们将深入探讨如何使用HttpURLConnection实现文件上传,同时也会涉及普通参数的传递。 首先,我们需要理解HTTP请求的基本结构。HTTP请求通常由以下几个部分组成:请求行、请求头、空行和请求体。在文件...
本话题主要关注如何使用`HttpURLConnection`来实现从本地目录读取资源并上传到远程服务器的功能。 首先,`HttpURLConnection`是`java.net.URL`类的子类,它可以建立与指定URL所代表的服务器的连接,并执行HTTP协议...
3. **限制大小**:设置上传文件大小限制,防止过大文件导致服务器资源耗尽。 4. **权限控制**:对上传的文件设置合适的权限,防止被非法访问。 通过以上步骤,你可以构建一个基本的图片上传系统,将Android设备上的...
本篇将详细讲解如何使用HttpURLConnection获取JSON数据并进行解析。首先,我们需要理解HttpURLConnection的基本用法,然后了解JSON数据的解析方法,以及如何在Android主线程和子线程之间通过Handler进行数据传递。 ...
7. **java.util.ArrayList** 和 **java.util.HashMap**: 如果POST数据包含多个参数,可以使用这些集合类来组织参数。ArrayList存储参数值的列表,HashMap存储参数名和对应的值。 8. **org.apache....
- 在Android客户端,可以使用`HttpURLConnection`的`setFixedLengthStreamingMode()`或`setChunkedStreamingMode()`来设置上传模式。 5. **服务器端处理**: - 服务器端通常使用Servlet来接收文件,这里使用了...
在Android平台上,将文件上传至服务器是常见的应用场景,例如用户可能需要分享图片、视频或者其他文件。本场景中,我们关注的是使用Java服务器(通常为Java Servlet)接收Android客户端上传的文件。以下是对整个过程...
使用HttpURLConnection进行联网请求的基本步骤如下: 1. **建立连接**:通过URL对象创建HttpURLConnection实例。 2. **设置请求方法**:调用`setRequestMethod()`,如`setRequestMethod("POST")`或`...
8. **多文件上传**:如果需要上传多个文件,可以使用循环或者递归的方式,对每个文件进行单独的上传操作,或者使用支持批量上传的API。 9. **异步处理**:考虑到文件上传可能耗时较长,应避免阻塞主线程。可以使用...
4. **安全措施**:确保上传的文件不会导致服务器资源耗尽或安全风险。例如,限制文件大小、类型,以及进行病毒扫描。 三、客户端下载文件 1. **获取URL**:客户端从服务器的响应中获取到文件URL。 2. **发起下载...
本课件“Android课件(URL+HttpURLConnection).zip”显然专注于讲解如何在Android应用程序中使用这些技术。下面我们将深入探讨URL和HttpURLConnection在Android开发中的应用和相关知识点。 1. **URL的理解与使用**...