在fragment中實現Android上傳圖片至本地JavaWeb服務器
阿新 • • 發佈:2018-05-09
prop prefix adt ilo err 1.10 response try 轉換成
服務器端:
需要一個接受文件的servlet,以及導入兩個包:commons-fileupload-1.3.1.jar 和 commons-io-2.4.jar
import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.util.List; import javax.servlet.ServletException; importjavax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItemFactory; import org.apache.commons.fileupload.disk.DiskFileItemFactory;import org.apache.commons.fileupload.servlet.ServletFileUpload; public class Upload extends HttpServlet { protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ try{ request.setCharacterEncoding("UTF-8"); // 設置處理請求參數的編碼格式 response.setContentType("text/html;charset=UTF-8"); // 設置Content-Type字段值 PrintWriter out = response.getWriter(); //下面的代碼開始使用Commons-UploadFile組件處理上傳的文件數據 FileItemFactory factory = new DiskFileItemFactory(); // 建立FileItemFactory對象 ServletFileUpload upload = new ServletFileUpload(factory); //分析請求,並得到上傳文件的FileItem對象 List<FileItem> items = upload.parseRequest(request); //從web.xml文件中的參數中得到上傳文件的路徑 String uploadPath = "E:\\A_HW\\"; File file = new File(uploadPath); if (!file.exists()) { file.mkdir(); } String filename = ""; // 上傳文件保存到服務器的文件名 InputStream is = null; // 當前上傳文件的InputStream對象 //循環處理上傳文件 for (FileItem item : items) { //處理普通的表單域 if (item.isFormField()) { if (item.getFieldName().equals("imageFile")) //圖片文件的name { //如果新文件不為空,將其保存在filename中 if (!item.getString().equals("")) filename = item.getString("UTF-8"); } } //處理上傳文件 else if (item.getName() != null && !item.getName().equals("")) { //從客戶端發送過來的上傳文件路徑中截取文件名 filename = item.getName().substring( item.getName().lastIndexOf("\\") + 1); is = item.getInputStream(); // 得到上傳文件的InputStream對象 } } //將路徑和上傳文件名組合成完整的服務端路徑 filename = uploadPath + filename; //如果服務器已經存在和上傳文件同名的文件,則輸出提示信息 if (new File(filename).exists()) { new File(filename).delete(); } //開始上傳文件 if (!filename.equals("")) { //用FileOutputStream打開服務端的上傳文件 FileOutputStream fos = new FileOutputStream(filename); byte[] buffer = new byte[8192]; // 每次讀8K字節 int count = 0; //開始讀取上傳文件的字節,並將其輸出到服務端的上傳文件輸出流中 while ((count = is.read(buffer)) > 0) { fos.write(buffer, 0, count); // 向服務端文件寫入字節流 } fos.close(); // 關閉FileOutputStream對象 is.close(); // InputStream對象 out.println("文件上傳成功!"); } }catch (Exception e) { e.printStackTrace(); } } }
註意:imageFile要和之後Android端名字的對應
客戶端:
我是直接通過拍照獲取的圖片,所以首先獲取圖片的位置
private void doTakePhoto() { Intent intent = new Intent(); // 指定開啟系統相機的Action intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); intent.addCategory(Intent.CATEGORY_DEFAULT); String time = String.valueOf(System.currentTimeMillis()); // 根據文件地址創建文件 File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/M2_test/" + time + ".jpg"); Log.i("Environment_path", Environment.getExternalStorageDirectory().getAbsolutePath()); file.getParentFile().mkdirs(); if (file.exists()) { file.delete(); } // 把文件地址轉換成Uri格式 Uri uri2 = Uri.fromFile(file); Uri uri = FileProvider.getUriForFile(getContext(), "com.f.myapplication", file); //添加權限 Log.i("uri",uri.toString()); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //臨時授權 intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); startActivityForResult(intent, REQUEST_CAMERA); String imagePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/M2_test/" + time + ".jpg"; imageCheck(uri2,imagePath); iniLocationMap(); // uploadImage(imagePath); }
獲取到的圖片進行查看,通過bundle傳遞image的uri
private void imageCheck(Uri uri,String img) { String imagepath = uri.toString(); Image_check image_check = new Image_check(); Bundle bundle = new Bundle(); bundle.putString("imagepath", imagepath); bundle.putString("img",img); image_check.setArguments(bundle); ft.replace(R.id.fragment_content,image_check); //這個是我fragment替換 ft.addToBackStack(null); ft.commit(); }
Image_check是一個Fragment可以查看圖片並通過點擊按鈕實現上傳文件(需要點擊預覽圖片,獲取到圖片位置,才能上傳圖片)
public class Image_check extends Fragment { private EditText et_beizhu; private Button btn_upload; private Button btn_look_pic; private ImageView iv; private FragActivity_Map fragActivity_map; String imagepath=""; String img; private FragmentManager fm; private FragmentTransaction ft; public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.image_check, container, false); fm = getFragmentManager(); ft = fm.beginTransaction(); fragActivity_map=new FragActivity_Map(); iv=view.findViewById(R.id.imageView); btn_upload= view.findViewById(R.id.btn_upload); btn_look_pic= view.findViewById(R.id.btn_look_pic); if (getArguments() != null) { imagepath = getArguments().getString("imagepath"); Log.i("image_check_image",imagepath); } btn_look_pic.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { iv.setImageURI( Uri.parse(imagepath) ); } }); btn_upload.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { uploadImage(imagepath); FragActivity_Map frag_map = new FragActivity_Map(); Bundle bundle = new Bundle(); bundle.putString("result_image", "ok_upload"); frag_map.setArguments(bundle); fm.beginTransaction().hide(Image_check.this).show(fragActivity_map).commit(); // ft.replace(R.id.fragment_content,frag_map); ft.addToBackStack(null); ft.commit(); } }); return view; } //線程上傳圖片 private void uploadImage(String imagePath) { Log.i("start upload", "start upload"); Log.i("start upload_path", "imagePath" + imagePath); NetworkTask networkTask = new NetworkTask(); networkTask.execute(imagePath); } public static Image_check newInstance(String text) { Image_check fragment = new Image_check(); Bundle bundle = new Bundle(); bundle.putString("imagepath", text); fragment.setArguments(bundle); return fragment; } }
NetworkTask 是一個實現連接javaweb服務器的線程並調用上傳文件的工具類 UploadUtil
class NetworkTask extends AsyncTask<String, Integer, String> { // 這裏就是JavaWeb服務器地址,servlet private final String ServerURL="http://192.168.1.105:8080/File_upload/Upload"; @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected String doInBackground(String... params) { // return doPost(params[0]); String uri = (params[0]); Uri u=Uri.parse((String) uri); File file = new File(u.getPath()); return UploadUtil.uploadFile(file, ServerURL); } @Override protected void onPostExecute(String result) { if (UploadUtil.SUCCESS.equalsIgnoreCase(result)) { Log.i("上傳結果", "上傳成功 "); } else { Log.i("上傳結果", "上傳失敗 "); } } }
UploadUtil工具類(啊哈,網上找的)
public class UploadUtil { private static final int TIME_OUT = 10 * 10000000; //超時時間 private static final String CHARSET = "utf-8"; //設置編碼 public static final String SUCCESS = "1"; public static final String FAILURE = "0"; public static String uploadFile(File file, String RequestURL) { String BOUNDARY = UUID.randomUUID().toString(); //邊界標識 隨機生成 String PREFIX = "--", LINE_END = "\r\n"; try { URL url = new URL(RequestURL); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setReadTimeout(TIME_OUT); conn.setConnectTimeout(TIME_OUT); conn.setDoInput(true); //允許輸入流 conn.setDoOutput(true); //允許輸出流 conn.setUseCaches(false); //不允許使用緩存 conn.setRequestMethod("POST"); //請求方式 conn.setRequestProperty("Charset", CHARSET); //設置編碼 conn.setRequestProperty("connection", "keep-alive"); conn.setRequestProperty("Content-Type", "multipart/form-data" + ";boundary=" + BOUNDARY); if (file != null) { OutputStream outputSteam = conn.getOutputStream(); DataOutputStream dos = new DataOutputStream(outputSteam); StringBuffer sb = new StringBuffer(); sb.append(PREFIX); sb.append(BOUNDARY); sb.append(LINE_END); /** * 這裏重點註意: * name裏面的值為服務器端需要key 只有這個key 才可以得到對應的文件 * filename是文件的名字,包含後綴名的 比如:abc.png */ Log.i("file.getName()",file.getName()); sb.append("Content-Disposition: form-data; name=\"imageFile\"; filename=\"" + file.getName() + "\"" + LINE_END); sb.append("Content-Type: application/octet-stream; charset=" + CHARSET + LINE_END); sb.append(LINE_END); dos.write(sb.toString().getBytes()); InputStream is = new FileInputStream(file); byte[] bytes = new byte[1024]; int len = 0; while ((len = is.read(bytes)) != -1) { dos.write(bytes, 0, len); } is.close(); dos.write(LINE_END.getBytes()); byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END).getBytes(); dos.write(end_data); dos.flush(); dos.close(); /** * 獲取響應碼 200=成功 * 當響應成功,獲取響應的流 */ int res = conn.getResponseCode(); Log.e("response code", "response code:" + res); if (res == 200) { return SUCCESS; } } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return FAILURE; } }
當然當中遇到了很多問題,必須要仔仔細細看錯誤提示啊
註意
- 開了Tomcat服務器後,要關閉電腦的防火墻,要不然可能連接不上
在fragment中實現Android上傳圖片至本地JavaWeb服務器