服务器端:
需要一个接受文件的 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;
- 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.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 服务器后, 要关闭电脑的防火墙, 要不然可能连接不上
来源: http://www.bubuko.com/infodetail-2593096.html