java 上傳圖片 cxf,servlet,spring 標準方式

1.標準的java上傳方式html

 

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
	}

}

而後配置servletjava

   <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 restspring

 

 

	接口定義
	@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,其實限制了圖片的類型,要求很嚴格。apache

 

 

/** 
     * 表單提交,文件上傳 
     * @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);  

接口的實現:json

 

實現方式不少種:服務器

以下是第一種,這是最簡單的方式,直接取出流,而後讀取app

 

@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";
	}

第二種:ide

 

 

	@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作上傳的時候還遇到了個問題,折騰了半天:post

 

筆者寫了個cxf的Interceptor 攔截器,實現了AbstractPhaseInterceptor<Message>,用來攔截客戶端傳過來的數據,作數據處理,好比加解密,身份認證,等等,可是筆者有把客戶端傳過來的流出來分析了以後,在回寫進去的操做,這麼一來就發生了一個問題,這裏處理的應該是字符流,而上傳圖片的時候是文件流,流只能讀取一次,筆者處理完了以後,cxf的接收實現類裏,在執行上面的讀取文件流的圖片的時候,就出現了個問題,筆者本來的圖片是122k,因爲攔截器的緣由,這時候把圖片寫到文件裏變成了200k,而後圖片就打不開了,要注意!!!

另外:writeToFile(ins,"d:\\"+ new String(dh.getName().getBytes("iso-8859-1"),"utf-8"));,這裏,紅色部分是爲了防止客戶端上傳的圖片中文名字亂碼,其實沒啥鳥用,由於咱們的文件流上傳以後,通常會用GUID 代替原來的文件名字。this

4.服務端 rest接口,直接接收客戶端的流

 

	/** 
     * 表單提交,文件上傳 
     * @return 
     */  
    @POST  
    @Path("/uploadimage")  
    @Consumes("application/binary")  
    public String uploadFileByForm(InputStream inputStream); 
相關文章
相關標籤/搜索