zoukankan      html  css  js  c++  java
  • Android上传文件至服务器(上)

    每一次都不能上首页,真悲催。。管理员让我上一次首页?
    很多时候我更愿意一个人写代码,与其在垃圾代码上改改改,我更愿意直接重构。

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


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

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

    文件上传的原理

    文件上传就是服务器通过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客户端可以构造一个请求,将文件上传上去。

  • 相关阅读:
    [视频监控]用状态机图展示Layout切换关系
    初次打开mysql5.6后
    eclipse 项目乱码
    java servlet 中遇到的编码问题
    解决HttpServletResponse输出的中文乱码问题
    The first day of my Blog
    最大子段和
    LOI 54 成立一周年纪(zuo)念(si)
    水题 逆序对 NOIP 2013 火柴排队
    搜索 由浅入深 之一 水题
  • 原文地址:https://www.cnblogs.com/kui0621/p/6183916.html
Copyright © 2011-2022 走看看