每一次都不能上首页,真悲催。。管理员让我上一次首页?

很多时候我更愿意一个人写代码,与其在垃圾代码上改改改,我更愿意直接重构。

整洁的代码简单直接。整洁的代码如同优美的散文。整洁的代码从不隐藏设计者的意图,充满了干净利落的抽象和直截了当的控制语句



(图片总是显示不好,过天换个主题。)

今天更新上传文件到服务器的内容。这两天需要将图片保存到服务器,因为一般不将图片等数据直接存储在数据库中,数据库中往往只存图片的路径,所以要将图片上传到服务器的某个文件夹中,路径保存在数据库中,这样就可以通过路径来取得图片了。

文件上传的原理

文件上传就是服务器通过request对象获取输入流(getInputStream),将浏览器上传的数据读取出来,保存到服务器端。

注意事项

  1. 请求方式必须为"POST"

  2. CONTENT_TYPE必须设置为mulitipart/form-data

  3. 如果通过网页上传文件的话需要使用组件

    <input type="file" name="file">

Apache-fileupload介绍

Apache-fileupload是Apache提供的方便文件上传的类,可以在commons中找到,官网网址是这个

FileUpload依赖于Commons IO,所以不要忘记包含Commons IO

顺便看一下User guide

  1. 在你确定保存文件之前,确保这是一个文件上传的请求。

    //检查是否是一个文件上传的请求
    boolean isMultipart = ServletFileUpload.isMultipartContent(request);
  2. 最简单的小例子

    //创建一个工厂对象
    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);
  3. 处理文件上传项

    Iterator<FileItem> iter = iterms.iterator();
    while(iter.hasNext()){
    FileItem item = iter.next();
    if(item.isFormField()){
    //普通的组件
    }else{
    //文件上传组件,将文件保存到服务器
    processUploadFile(item);
    }
    }
  4. 官网还有限制大小、清理等功能,限于时间,我没仔细看,感兴趣的可以自己查看相关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上传文件至服务器(上)的更多相关文章

  1. 用winscp从本地上传文件到服务器上出现复制文件到远端时错误。

    用winscp从本地上传文件到服务器上出现复制文件到远端时错误. 错误码:4 服务器返回的错误消息:write failed 报错如下图所示: 分析过程: 1.刚开始以为是权限不够,后面上网查了一下是 ...

  2. ubuntu16.04安装mongodb,创建数据库管理员,上传文件到服务器上

    1.导入软件源得公钥 sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv EA312927 2.为mongodb创建软件 ...

  3. android上传文件到服务器

    package com.spring.sky.image.upload.network; import java.io.DataOutputStream; import java.io.File; i ...

  4. Android端通过HttpURLConnection上传文件到服务器

    Android端通过HttpURLConnection上传文件到服务器 一:实现原理 最近在做Android客户端的应用开发,涉及到要把图片上传到后台服务器中,自己选择了做Spring3 MVC HT ...

  5. android -上传文件到服务器

    android上传文件到服务器       重点:最好是设置好content-type这些参数的配置!     package com.spring.sky.image.upload.network; ...

  6. WPF上传文件到服务器

    利用WebClient 上传文件到服务器 创建一个空网站,创建一个UploadFile.aspx项, 服务器报500错误:检查文件保存路径是否存在,检查文件大小限制 protected void Pa ...

  7. joomla安装插件报错:上传文件到服务器发生了一个错误。 过小的PHP文件上传尺寸

    在安装joomla的AKeeba插件的时候报错如下:上传文件到服务器发生了一个错误. 过小的PHP文件上传尺寸.解决方法是修改php.ini文件,打开文件后搜索upload_max_filesize! ...

  8. C 上传文件到服务器(含接收端源码)

    本文demo下载地址:http://www.wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId=1067 实例向大家展示了如何用Visua ...

  9. C# FTP上传文件至服务器代码

    C# FTP上传文件至服务器代码 /// <summary> /// 上传文件 /// </summary> /// <param name="fileinfo ...

随机推荐

  1. C# 中实现单例模式

    文章目录 简介 不安全线程的单例模式 简单安全线程带锁 双重检查 - 带锁 安全初始化 安全并且懒汉式静态初始化 带泛型的懒汉式单例 异常 提高效率 总结 简介 单例模式是软件工程中广为人知的设计模式 ...

  2. SQL Server 执行计划利用统计信息对数据行的预估原理以及SQL Server 2014中预估策略的改变

    前提  本文仅讨论SQL Server查询时, 对于非复合统计信息,也即每个字段的统计信息只包含当前列的数据分布的情况下, 在用多个字段进行组合查询的时候,如何根据统计信息去预估行数的. 利用不同字段 ...

  3. STM32CubeMX安装指南

    1.STM32CubeMX软件下载 地址:http://pan.baidu.com/s/1bn8sXOV 密码:6u3p 2.安装     1)安装Java SDK     2)安装SetupSTM3 ...

  4. Unity实现滑页嵌套(解决ScrollRect嵌套冲突问题)

    简介 由于项目需要+有网友咨询,所以做了个横向滑页+某一横向滑页中有竖向滑页的demo,实现有点绕弯子,但基本功能还是比较完善,发上来共享一下. 效果 思路 第一步的思路是自己判断触屏拖动位置,然后控 ...

  5. [WCF编程]6.绑定行为

    一.绑定行为概述 为了支持服务端的其它本地特性,WCF定义了行为的概念.行为就是服务的本地特性,不会影响服务的通信模式.客户端并不知道服务端行为,所以行为不会出现在服务的绑定和发布的元数据中.说下WC ...

  6. 流行ORM产品优缺点分析--EntityFramework、NHibernate、PetaPoco

    什么是ORM? ORM的全称是Object Relational Mapping,即对象关系映射.它的实现思想就是将关系数据库中表的数据映射成为对象,以对象的形式展现,这样开发人员就可以把对数据库的操 ...

  7. NanUI for Winform发布,让Winform界面设计拥有无限可能

    如今,尽管WPF.UWP大行其道,大有把Winform打残干废的趋势.但是还是有那么一波顽固不化的老家伙们固守着Winform,其中就包括我. 好吧,既然都说Winform做得软件不如WPF界面美观效 ...

  8. 怎么搭建EF的环境?(Entity Framework)

    1.EF是什么? EF是.net封装的一个用于数据库交互的实体层框架,它的全称是Entity Framework. 2.EF搭建: 新建之后,我们就可以看到里面的内容: 我们可以分别看一下它里面有些什 ...

  9. Objective-c的@property(atomic,nonatomic,readonly,readwrite,assign,retain,copy,getter,setter) 属性特性

    assign:指定setter方法用简单的赋值,这是默认操作.你可以对标量类型(如int)使用这个属性.你可以想象一个float,它不是一个对象,所以它不能retain.copy. retain:指定 ...

  10. overflow

    1. 隐藏x轴滚动条,垂直有滚动条: <body> <div style="width:100px;height:150px;overflow:scroll;overflo ...