Android上传文件至服务器(上)
每一次都不能上首页,真悲催。。管理员让我上一次首页?
很多时候我更愿意一个人写代码,与其在垃圾代码上改改改,我更愿意直接重构。
整洁的代码简单直接。整洁的代码如同优美的散文。整洁的代码从不隐藏设计者的意图,充满了干净利落的抽象和直截了当的控制语句

(图片总是显示不好,过天换个主题。)
今天更新上传文件到服务器的内容。这两天需要将图片保存到服务器,因为一般不将图片等数据直接存储在数据库中,数据库中往往只存图片的路径,所以要将图片上传到服务器的某个文件夹中,路径保存在数据库中,这样就可以通过路径来取得图片了。
文件上传的原理
文件上传就是服务器通过request对象获取输入流(getInputStream),将浏览器上传的数据读取出来,保存到服务器端。
注意事项
请求方式必须为"POST"
CONTENT_TYPE必须设置为mulitipart/form-data如果通过网页上传文件的话需要使用组件
<input type="file" name="file">
Apache-fileupload介绍
Apache-fileupload是Apache提供的方便文件上传的类,可以在commons中找到,官网网址是这个
FileUpload依赖于Commons IO,所以不要忘记包含Commons IO包
顺便看一下User guide
在你确定保存文件之前,确保这是一个文件上传的请求。
//检查是否是一个文件上传的请求
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
最简单的小例子
//创建一个工厂对象
DiskFileItemFactory factory = new DiskFileItemFactory();
//配置临时文件存储目录
ServletContext servletContext = this.getServletConfig().getServletContext();
File repository = (File)servletContext.getAttribute("javax.servlet.context.tempdir");
factory.setRepository(repository);
//创建一个文件上传处理对象
ServletFileUpload upload = new ServletFileUpload(factory);
//解析请求
List<FileItem> iterms = upload.parseRequest(request);
处理文件上传项
Iterator<FileItem> iter = iterms.iterator();
while(iter.hasNext()){
FileItem item = iter.next();
if(item.isFormField()){
//普通的组件
}else{
//文件上传组件,将文件保存到服务器
processUploadFile(item);
}
}
官网还有限制大小、清理等功能,限于时间,我没仔细看,感兴趣的可以自己查看相关API
服务端完整实现
添加一个处理文件上传的Servlet,别忘了在Web.xml中配置,我刚开始不熟悉,想不起来配置了。多注意
public class UploadServlet extends HttpServlet {
PrintWriter out = null;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
out = response.getWriter();
//判断表单是否支持文件上传,就是查看enctype是否是:"multipart/form-data"
boolean isMultipartContent = ServletFileUpload.isMultipartContent(request);
if (!isMultipartContent) {
throw new RuntimeException("表单不支持文件上传");
}
System.out.println("支持文件上传");
//创建一个DiskFilefactory工厂类
DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
//配置一个临时文件存储目录
ServletContext servletContext = this.getServletConfig().getServletContext();
File repositoryFile = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
diskFileItemFactory.setRepository(repositoryFile);
//创建一个新的文件上传处理类
ServletFileUpload upload = new ServletFileUpload(diskFileItemFactory);
//防止中文乱码
upload.setHeaderEncoding("UTF-8");
//解析请求服务
try {
List<FileItem> itemsList = upload.parseRequest(request);
//遍历表单项数据
for (FileItem fileItem : itemsList) {
if (fileItem.isFormField()) {
//代表是普通表单项
}
else {
//代表是文件上传表单项
processUploadField(fileItem);
}
}
} catch (FileUploadException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void processUploadField(FileItem fileItem) throws Exception {
// TODO Auto-generated method stub
//创建文件输入流
try {
InputStream inputStream = fileItem.getInputStream();
String directoryRealPathString = this.getServletContext().getRealPath("/WEB-INF/upload");
File storeDirectory = new File(directoryRealPathString);
if (!storeDirectory.exists()) {
storeDirectory.mkdirs();
}
//得到上传文件的名字
String fileName = fileItem.getName();
System.out.println("文件上传的名字是:"+fileName);
if (fileName !=null) {
fileName = fileName.substring(fileName.lastIndexOf(File.separator)+1);
}
//解决文件同名问题
fileName = UUID.randomUUID()+"_"+fileName;
//按日期进行目录打散
String childDirectoryString = makeChildDirectory(storeDirectory,fileName);
System.out.println("上传的文件夹是:"+childDirectoryString);
// 文件的存储路径
String filePath = childDirectoryString+File.separator+fileName;
//上传成功,删除临时文件
fileItem.write(new File(storeDirectory,filePath));
//文件的存储路径是
System.out.println("文件的存储路径"+filePath);
// 文件存储的绝对路径
System.out.println("绝对路径:"+storeDirectory+filePath);
out.print("文件上传成功");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw e;
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw e;
}
}
//创建文件存储目录
private String makeChildDirectory(File storeDirectory, String fileName) {
// TODO Auto-generated method stub
int hashCode = fileName.hashCode();
System.out.println("哈希吗:"+hashCode);
//把哈希码转换为16进制的字符
String code =Integer.toHexString(hashCode);
System.out.println(code);
String childDirectory = code.charAt(0)+File.separator+code.charAt(1);
//创建制定目录
File file = new File(storeDirectory,childDirectory);
if (!file.exists()) {
file.mkdirs();
}
return childDirectory;
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
### 总结
上面是服务端的实现,下一篇文章更新客户端的实现,jsp网页直接通过上传组件可以上传文件,而Android客户端可以构造一个请求,将文件上传上去。
Android上传文件至服务器(上)的更多相关文章
- 用winscp从本地上传文件到服务器上出现复制文件到远端时错误。
用winscp从本地上传文件到服务器上出现复制文件到远端时错误. 错误码:4 服务器返回的错误消息:write failed 报错如下图所示: 分析过程: 1.刚开始以为是权限不够,后面上网查了一下是 ...
- ubuntu16.04安装mongodb,创建数据库管理员,上传文件到服务器上
1.导入软件源得公钥 sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv EA312927 2.为mongodb创建软件 ...
- android上传文件到服务器
package com.spring.sky.image.upload.network; import java.io.DataOutputStream; import java.io.File; i ...
- Android端通过HttpURLConnection上传文件到服务器
Android端通过HttpURLConnection上传文件到服务器 一:实现原理 最近在做Android客户端的应用开发,涉及到要把图片上传到后台服务器中,自己选择了做Spring3 MVC HT ...
- android -上传文件到服务器
android上传文件到服务器 重点:最好是设置好content-type这些参数的配置! package com.spring.sky.image.upload.network; ...
- WPF上传文件到服务器
利用WebClient 上传文件到服务器 创建一个空网站,创建一个UploadFile.aspx项, 服务器报500错误:检查文件保存路径是否存在,检查文件大小限制 protected void Pa ...
- joomla安装插件报错:上传文件到服务器发生了一个错误。 过小的PHP文件上传尺寸
在安装joomla的AKeeba插件的时候报错如下:上传文件到服务器发生了一个错误. 过小的PHP文件上传尺寸.解决方法是修改php.ini文件,打开文件后搜索upload_max_filesize! ...
- C 上传文件到服务器(含接收端源码)
本文demo下载地址:http://www.wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId=1067 实例向大家展示了如何用Visua ...
- C# FTP上传文件至服务器代码
C# FTP上传文件至服务器代码 /// <summary> /// 上传文件 /// </summary> /// <param name="fileinfo ...
随机推荐
- Cesium原理篇:6 Renderer模块(2: Texture)
Texture也是WebGL中重要的概念,使用起来也很简单.但有句话叫大道至简,如果真的想要用好纹理,里面的水其实也是很深的.下面我们来一探究竟. 下面是WebGL中创建一个纹理的最简过程: var ...
- Apworks框架实战(三):单元测试与持续集成
虽然这部分内容并没有过多地讨论Apworks框架的使用,但这部分内容非常重要,它与Apworks框架本身的设计紧密相关,也是进一步了解Apworks框架设计的必修课. 单元测试与持续集成概述 在敏捷开 ...
- do{...}while(0)的妙用
在学习第一门编程语言时,就已经介绍了顺序分支.条件分支.循环分支.比如循环分支有for.while.do-while语句.在随后的学校及工作中,如果手工循环一般使用for.while,很少使用do-w ...
- 自己封装的一个LoadRes组件
这两周一直太忙,没有好好处理上上上周遇到的一个让我加班到凌晨的问题,这个问题是判断flash的加载. 之前的思路是让flash的人在制作flash的时候,加入了一个回调方法,该方法再会回调我页面的方法 ...
- The Practice of .NET Cross-Platforms
0x01 Preface This post is mainly to share the technologies on my practice about the .NET Cross-Platf ...
- ASP.NET-Web项目运行缓慢-AjaxMin在搞鬼
AjaxMin 4.8版本是没问题,出现问题的时候是AjaxMin 5.3.xxxxx版本,起初我也不知道是AjaxMin出现问题一直以为是因为我大幅度修改Web项目架构,以及采用大量反射后所带来的后 ...
- C#多线程编程
一.使用线程的理由 1.可以使用线程将代码同其他代码隔离,提高应用程序的可靠性. 2.可以使用线程来简化编码. 3.可以使用线程来实现并发执行. 二.基本知识 1.进程与线程:进程作为操作系统执行程序 ...
- webapi修改tt模板给字段添加JsonIgnore特性解决转换json循环引用问题
0.问题描述 EF生成的model带有导航属性,则json序列化会报循环引用错误,尝试如下 protected void Application_Start() { GlobalConfigurati ...
- int与Integer的爱恨情仇
int作为java中元老级的数据类型,可谓无处不在,自从jdk5诞生了Integer,从此不在孤单. 为什么要设计Integer呢?它与int有什么区别? 一.Integer是int的包装类型,是引用 ...
- Linux命令详解之—tail命令
tail命令也是一个非常常用的文件查看类的命令,今天就为大家介绍下Linux tail命令的用法. 更多Linux命令详情请看:Linux命令速查手册 Linux tail命令主要用来从指定点开始将文 ...