zoukankan      html  css  js  c++  java
  • java 上传图片 cxf,servlet,spring 标准方式

    1.标准的java上传方式

    package com.weds.common.pay.servlet;
    import java.io.File;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.List;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.commons.fileupload.FileItem;
    import org.apache.commons.fileupload.FileUploadException;
    import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    import org.apache.commons.fileupload.servlet.ServletFileUpload;
    import org.json.JSONObject;
    
    import com.weds.framework.core.common.model.JsonResult;
    
    public class UploadServlet extends HttpServlet {
    
    	/**
    	 * Destruction of the servlet. <br>
    	 */
    	public void destroy() {
    		super.destroy(); // Just puts "destroy" string in log
    		// Put your code here
    	}
    
    	/**
    	 * The doGet method of the servlet. <br>
    	 *
    	 * This method is called when a form has its tag value method equals to get.
    	 * 
    	 * @param request the request send by the client to the server
    	 * @param response the response send by the server to the client
    	 * @throws ServletException if an error occurred
    	 * @throws IOException if an error occurred
    	 */
    	public void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    
    		response.setContentType("text/html;charset=utf-8");
    		request.setCharacterEncoding("utf-8");
    		response.setCharacterEncoding("utf-8");
    		PrintWriter out = response.getWriter();
    		//实现上传的类
    		DiskFileItemFactory factory = new DiskFileItemFactory();//磁盘对象
    		
    		ServletFileUpload upload = new ServletFileUpload(factory);//声明解析request对象
    		upload.setFileSizeMax(2*1024*1024);//设置每个文件最大为2M
    		upload.setSizeMax(4*1024*1024);//设置一共最多上传4M
    		
    		try {
    			List<FileItem> list = upload.parseRequest(request);//解析
    			for(FileItem item:list){//判断FileItem类对象封装的数据是一个普通文本表单字段,还是一个文件表单字段,如果是普通表单字段则返回true,否则返回false。
    				if(!item.isFormField()){
    					//获取文件名
    					String fileName = item.getName();
    					//获取服务器端路径
    					String file_upload_loader =this.getServletContext().getRealPath("");
    					System.out.println("上传文件存放路径:"+file_upload_loader);
    					//将FileItem对象中保存的主体内容保存到某个指定的文件中。
    					item.write(new File(file_upload_loader+File.separator+fileName));
    				}else{
    					if(item.getFieldName().equalsIgnoreCase("username")){
    						String username = item.getString("utf-8");//将FileItem对象中保存的数据流内容以一个字符串返回
    						System.out.println(username);
    					}
    					if(item.getFieldName().equalsIgnoreCase("password")){
    						String password = item.getString("utf-8");
    						System.out.println(password);
    					}
    				}
    			}
    			//返回响应码(ResultCode)和响应值(ResultMsg)简单的JSON解析
    			JsonResult jsonResult=new JsonResult();
    			JSONObject json = new JSONObject();
    			JSONObject jsonObject = new JSONObject();
    			json.put("ResultCode",jsonResult.getCode());
    			json.put("ResultMsg",jsonResult.getMsg());
    			jsonObject.put("upload",json);
    			//System.out.println(jsonObject.toString());
    			out.print(jsonObject.toString());
    			
    		} catch (FileUploadException e) {
    			e.printStackTrace();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}finally{
    			out.close();
    		}
    	}
    
    	/**
    	 * The doPost method of the servlet. <br>
    	 *
    	 * This method is called when a form has its tag value method equals to post.
    	 * 
    	 * @param request the request send by the client to the server
    	 * @param response the response send by the server to the client
    	 * @throws ServletException if an error occurred
    	 * @throws IOException if an error occurred
    	 */
    	public void doPost(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    
    		doGet(request,response);
    	}
    
    	/**
    	 * Initialization of the servlet. <br>
    	 *
    	 * @throws ServletException if an error occurs
    	 */
    	public void init() throws ServletException {
    		// Put your code here
    	}
    
    }

    然后配置servlet

       <servlet>
            <servlet-name>upload</servlet-name>
            <servlet-class>com.weds.common.pay.servlet.UploadServlet</servlet-class>
            <load-on-startup>3</load-on-startup>
       </servlet>
       <servlet-mapping>
           <servlet-name>upload</servlet-name>
           <url-pattern>/upload</url-pattern>
       </servlet-mapping>

    2. 标准java 通过 request的方式 笔者用的是spring + Apache cxf rest

    	接口定义
    	@POST  
    	@Path("/upload")
    	@Consumes(MediaType.MULTIPART_FORM_DATA)//当前方法接收的参数类型
        public String uploadFile();
    接收实现
    @Override
    	public String uploadFile() {
    		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
    				.getRequestAttributes()).getRequest();
    		// 实现上传的类
    		DiskFileItemFactory factory = new DiskFileItemFactory();// 磁盘对象
    		ServletFileUpload upload = new ServletFileUpload(factory);// 声明解析request对象
    		upload.setFileSizeMax(2 * 1024 * 1024);// 设置每个文件最大为2M
    		upload.setSizeMax(4 * 1024 * 1024);// 设置一共最多上传4M
    		try {
    			List<FileItem> list = upload.parseRequest(request);// 解析
    			for (FileItem item : list) {// 判断FileItem类对象封装的数据是一个普通文本表单字段,还是一个文件表单字段,如果是普通表单字段则返回true,否则返回false。
    				if (!item.isFormField()) {
    					// 获取文件名
    					String fileName = item.getName();
    					// 获取服务器端路径
    					String file_upload_loader = request.getServletContext()
    							.getRealPath("");
    					System.out.println("上传文件存放路径:" + file_upload_loader);
    					// 将FileItem对象中保存的主体内容保存到某个指定的文件中。
    					item.write(new File(file_upload_loader + File.separator
    							+ fileName));
    				} else {
    					if (item.getFieldName().equalsIgnoreCase("username")) {
    						String username = item.getString("utf-8");// 将FileItem对象中保存的数据流内容以一个字符串返回
    						System.out.println(username);
    					}
    					if (item.getFieldName().equalsIgnoreCase("password")) {
    						String password = item.getString("utf-8");
    						System.out.println(password);
    					}
    				}
    			}
    		} catch (FileUploadException e) {
    			e.printStackTrace();
    		} catch (Exception e) {
    			e.printStackTrace();
    		} finally {
    			// out.close();
    		}
    		return "ok";
    	}
    注意这里获取request的时候,必须用上面的写法,通过 @Autowired注入获取request的方式在这里是不能用的,原因不详,求大神指点。

    3.cxf rest 风格上传实现 @Multipart的 type是可以省略的,下面的写法,尤其是image,其实限制了图片的类型,要求很严格。

    /** 
         * 表单提交,文件上传 
         * @return 
         */  
        @POST  
        @Path("/uploadimage")  
        @Consumes("multipart/form-data")  
        public String uploadFileByForm(  
                @Multipart(value="id",type="text/plain")String id,  
                @Multipart(value="name",type="text/plain")String name,  
                @Multipart(value="file",type="image/png")Attachment image);  

    接口的实现:

    实现方式很多种:

    如下是第一种,这是最简单的方式,直接取出流,然后读取

    @Override
    	public String uploadFileByForm(
    			@Multipart(value = "id", type = "text/plain") String id,
    			@Multipart(value = "name", type = "text/plain") String name,
    			@Multipart(value = "file", type = "image/png") Attachment image) {
    		try {
    			OutputStream out = new FileOutputStream(new File("d:\a.png"));
    			image.getDataHandler().writeTo(out);
    			out.close();
    		} catch (Exception e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		return "ok";
    	}

    第二种:

    	@Override
    	public String uploadFileByForm(
    			@Multipart(value = "id", type = "text/plain") String id,
    			@Multipart(value = "name", type = "text/plain") String name,
    			@Multipart(value = "file", type = "image/png") Attachment image) {
    		System.out.println("id:" + id);
    		System.out.println("name:" + name);
    		DataHandler dh = image.getDataHandler();
    		try {
    			InputStream ins = dh.getInputStream();
    			writeToFile(ins,"d:\"+ new String(dh.getName().getBytes("iso-8859-1"),"utf-8"));
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		return "ok";
    	}
    
    	private void writeToFile(InputStream ins, String path) {		
    		try {
    			OutputStream out = new FileOutputStream(new File(path));
    			byte[] bytes = new byte[1024];
    			while (ins.read(bytes) != -1) {
    				out.write(bytes);
    			}
    			out.flush();
    			out.close();
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    当然 writeToFile方法也可以这么实现:	
    private void writeToFile(InputStream ins, String path) {
    		try {
    			OutputStream out = new FileOutputStream(new File(path));
    			int read = 0;
    			byte[] bytes = new byte[1024];
    			while ((read = ins.read(bytes)) != -1) {
    				out.write(bytes, 0, read);
    			}
    			out.flush();
    			out.close();
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}


    注意:笔者在用cxf rest做上传的时候还遇到了个问题,折腾了半天:

    笔者写了个cxf的Interceptor 拦截器,实现了AbstractPhaseInterceptor<Message>,用来拦截客户端传过来的数据,做数据处理,比如加解密,身份认证,等等,但是笔者有把客户端传过来的流出来分析了之后,在回写进去的操作,这么一来就发生了一个问题,这里处理的应该是字符流,而上传图片的时候是文件流,流只能读取一次,笔者处理完了之后,cxf的接收实现类里,在执行上面的读取文件流的图片的时候,就出现了个问题,笔者原本的图片是122k,由于拦截器的原因,这时候把图片写到文件里变成了200k,然后图片就打不开了,要注意!!!

    另外:writeToFile(ins,"d:\"+ new String(dh.getName().getBytes("iso-8859-1"),"utf-8"));,这里,红色部分是为了防止客户端上传的图片中文名字乱码,其实没啥鸟用,因为我们的文件流上传之后,一般会用GUID 代替原来的文件名字。

    4.服务端 rest接口,直接接收客户端的流

    	/** 
         * 表单提交,文件上传 
         * @return 
         */  
        @POST  
        @Path("/uploadimage")  
        @Consumes("application/binary")  
        public String uploadFileByForm(InputStream inputStream); 



  • 相关阅读:
    JAVA EE社团管理升级版-项目展示(微信小程序)
    JAVA EE社团管理升级版-微信WEB管理端说明文档
    python爬虫19 | 遇到需要的登录的网站怎么办?用这3招轻松搞定!
    python爬虫20 | 小帅b教你如何使用python识别图片验证码
    python爬虫16 | 你,快去试试用多进程的方式重新去爬取豆瓣上的电影
    python爬虫17 | 听说你又被封 ip 了,你要学会伪装好自己,这次说说伪装你的头部
    python爬虫18 | 就算你被封了也能继续爬,使用IP代理池伪装你的IP地址,让IP飘一会
    python爬虫15 | 害羞,用多线程秒爬那些万恶的妹纸们,纸巾呢?
    python爬虫13 | 秒爬,这多线程爬取速度也太猛了,这次就是要让你的爬虫效率杠杠的
    python爬虫14 | 就这么说吧,如果你不懂python多线程和线程池,那就去河边摸鱼!
  • 原文地址:https://www.cnblogs.com/caoheyang911016/p/6169928.html
Copyright © 2011-2022 走看看