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);
相關文章
- laravel之標準上傳圖片Laravel
- spring boot 圖片上傳Spring Boot
- spring 對上傳圖片處理Spring
- java,springboot + thymeleaf 上傳圖片、刪除圖片到伺服器、本地,壓縮圖片上傳(有些圖片會失真),原圖上傳JavaSpring Boot伺服器
- Java和PHP兩種方式實現上傳圖片到新浪微博的圖床JavaPHP圖床
- Retrofit+RxJava上傳圖片上傳圖片到後臺RxJava
- Java實現圖片上傳到伺服器,並把上傳的圖片讀取出來Java伺服器
- 【easyui 】上傳圖片UI
- 上傳圖片jsJS
- 使用Vue實現圖片上傳的三種方式Vue
- 用Vue來實現圖片上傳多種方式Vue
- 圖片上傳及圖片處理
- php圖片上傳之圖片轉換PHP
- 新浪sae 上傳java war包出現not a javax.servlet.ServletJavaServlet
- 多圖片formpost上傳ORM
- input file圖片上傳
- PHP上傳圖片類PHP
- 圖片檔案上傳
- vue 上傳圖片進行壓縮圖片Vue
- Ueditor 上傳圖片自動新增水印(只能上傳圖片,上傳檔案報錯)
- 學姐,影片上傳不了,我上傳了圖片
- 求高手解決用java限制上傳圖片大小!!Java
- Laravel 使用 FastDFS 上傳圖片LaravelAST
- koa 圖片上傳詳解
- Vue圖片裁剪上傳元件Vue元件
- 圖片上傳方案詳解
- js上傳圖片壓縮JS
- vue圖片預覽上傳Vue
- Typora上傳圖片設定
- laravel 上傳附件-不是圖片--Laravel
- js圖片上傳預覽JS
- curl上傳圖片的大坑
- 微信小程式 圖片上傳微信小程式
- input file美化 --上傳圖片
- laravel上傳圖片報錯Laravel
- PHP配置CKEditor上傳圖片PHP
- vue 實現貼上上傳圖片Vue
- 自定義上傳圖片拼圖遊戲遊戲