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客户端可以构造一个请求,将文件上传上去。

  • 相关阅读:
    Python中所有的关键字
    关于selenium的8种元素定位
    对提示框的操作
    selenium+webservice进行百度登录
    MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled...报错解决
    Vue中使用echarts
    npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142解决方法
    插入排序
    冒泡排序优化
    roject 'org.springframework.boot:spring-boot-starter-parent:XXX' not found 解决
  • 原文地址:https://www.cnblogs.com/kui0621/p/6183916.html
Copyright © 2011-2022 走看看