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);