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

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

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



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

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

文件上传的原理

文件上传就是服务器通过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. 表空间基于时间点的恢复(TSPITR)

    环境:RHEL 6.4 + Oracle 11.2.0.4 准备模拟环境 1. 验证表空间的依赖性 2. 确定执行TSPITR后会丢失的对象 3. 自动执行TSPITR Reference 准备模拟环 ...

  2. java多线程--几个多线程面试题小结

    自学了一段时间的多线程知识,尝试了做了几个编程题,发现想象中很简单的功能,自己真写起来要花费远超自己想象的功夫,知识点易学,不易用啊. 面试题1:编写程序实现,子线程循环10次,接着主线程循环20次, ...

  3. spring笔记--事务管理之声明式事务

    事务简介: 事务管理是企业级应用开发中必不可少的技术,主要用来确保数据的完整性和一致性, 事务:就是一系列动作,它们被当作一个独立的工作单元,这些动作要么全部完成,要么全部不起作用. Spring中使 ...

  4. JavaWeb学习总结(五十二)——使用JavaMail创建邮件和发送邮件

    一.RFC882文档简单说明 RFC882文档规定了如何编写一封简单的邮件(纯文本邮件),一封简单的邮件包含邮件头和邮件体两个部分,邮件头和邮件体之间使用空行分隔. 邮件头包含的内容有: from字段 ...

  5. 【PHP面向对象(OOP)编程入门教程】17.克隆对象__clone()方法

    有的时候我们需要在一个项目里面,使用两个或多个一样的对象,如果你使用“new”关键字重新创建对象的话,再赋值上相同的属性,这样做比较烦琐而且也容易出错,所以要根据一个对象完全克隆出一个一模一样的对象, ...

  6. C#读取数据库中的表

    private int ExistOrNot(string name)    //判断当前数据表是否存在 { con = new SqlConnection(s); DataSet ds = new ...

  7. String的按值传递,java传参都是传值

    java中对象作为参数传递给一个方法,到底是值传递,还是引用传递? String和int参数传递是按值传递还是引用传递? 一道面试题目,String的传递: public String change( ...

  8. Spring整合Ehcache管理缓存

    前言 Ehcache 是一个成熟的缓存框架,你可以直接使用它来管理你的缓存. Spring 提供了对缓存功能的抽象:即允许绑定不同的缓存解决方案(如Ehcache),但本身不直接提供缓存功能的实现.它 ...

  9. Sql Server之使用T_SQL创建,修改,查看数据库信息

    一.使用Transact_SQL创建数据库 Transact_SQL语法如下:  create database database_name   [ on     [primary]  [<fi ...

  10. aspx后台传递Json到前台的两种接收方法

    第一种:前台接收 dataType: "json",                success: function (data) {                    va ...