将小文件上似到java web

今天来讲一下,如何将安卓设备上的小文件上传到java web的服务器上。
  首先,如果条件允许需要搭建一局域网,没有条件的话也可以在同一开发电脑上测试
  安卓设备上的小文件无法直接上传到服务器上,需要通过一个api来实现功能。因此代码也可以分为两部份,即:服务端(api)和应用端(安卓设备)。
  服务端(api)代码实现
  1.打开eclipse,打开或新建一个java web网站(请确保你的电脑已经安装Tomcat)。
  2.复制并引用三个jar包。commons-fileupload-1.2.1.jar、commons-io-1.4.jar、servlet-api.jar。
  3.新建一个类,这里命名为UploadHandleServlet,并写入代码,代码如下:

package firstweb;


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
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.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class UploadHandleServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
                //得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全
                String savePath  = this.getServletContext().getRealPath("/upload");
                System.out.println(savePath);
                File file = new File(savePath);
                //判断上传文件的保存目录是否存在
                if (!file.exists() && !file.isDirectory()) {
                    System.out.println(savePath+"目录不存在,需要创建");
                    //创建目录
                    file.mkdir();
                }
                //消息提示
                String message = "";
                try{
                    
                    List<FileItem> list = upload.parseRequest(request);
                    for(FileItem item : list){
                        //如果fileitem中封装的是普通输入项的数据
                        if(item.isFormField()){
                            String name = item.getFieldName();
                            //解决普通输入项的数据的中文乱码问题
                            String value = item.getString("UTF-8");
                            //value = new String(value.getBytes("iso8859-1"),"UTF-8");
                            System.out.println(name + "=" + value);
                        }else{//如果fileitem中封装的是上传文件
                            //得到上传的文件名称,
                            String filename = item.getName();
                            System.out.println(filename);
                            if(filename==null || filename.trim().equals("")){
                                continue;
                            }
                            //注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如:  c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt
                            //处理获取到的上传文件的文件名的路径部分,只保留文件名部分
                            filename = filename.substring(filename.lastIndexOf("\\")+1);
                            //获取item中的上传文件的输入流
                            InputStream in = item.getInputStream();
                            //创建一个文件输出流
                            FileOutputStream out = new FileOutputStream(savePath + "\\" + filename);
                            //创建一个缓冲区
                            byte buffer[] = new byte[1024];
                            //判断输入流中的数据是否已经读完的标识
                            int len = 0;
                            //循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据
                            while((len=in.read(buffer))>0){
                                //使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\\" + filename)当中
                                out.write(buffer, 0, len);
                            }
                            //关闭输入流
                            in.close();
                            //关闭输出流
                            out.close();
                            //删除处理文件上传时生成的临时文件
                            item.delete();
                            message = "文件上传成功!";
                        }
                    }
                }catch (Exception e) {
                    message= "文件上传失败!";
                    e.printStackTrace();

                }
                response.setHeader("Content-type", "text/html;charset=UTF-8"); //中文乱码解决
                response.getWriter().write(message);
//                request.setAttribute("message",message);
//                request.getRequestDispatcher("/message.jsp").forward(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doGet(request, response);
    }
}

4.项目节点下有一个WebContent节点,在其上面右键new(新建)一个jsp页面,这里为取名为upload代码如下。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>文件上传</title>
    
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->
  </head>
  
  <body>
   <form action="<%=path %>/UploadHandleServlet" enctype="multipart/form-data" method="post">
  
   上传文件1:<input type="file" name="file1"><br>

   <input type="submit" value="提交">
   
       
   </form>
  </body>
</html>

5.继续在WebContent节点新建一个名为message.jsp网页,代码如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>提示消息</title>
    
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>
  
  <body>
     ${message}
  </body>
</html>

6.在WebContent\WEB-INF新建一个配置文件——web.xml。代码如下

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>NetServer</display-name>
  <welcome-file-list>
    <welcome-file>upload.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <servlet-name>UploadHandleServlet</servlet-name>
    <servlet-class>firstweb.UploadHandleServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>UploadHandleServlet</servlet-name>
    <url-pattern>/UploadHandleServlet</url-pattern>
</servlet-mapping>
</web-app>

7.保存前面编写的所有文件,运行(run as server)或发布网站。
  试着在网页上上传一个文件,如果上传成功,表明服务端代码已全部完成。
  应用端(安卓设备)代码实现:
  1.打开andoid studio,新建或打开一个项目。
  2.引入两个jar包okhttp-3.2.0.jar、okio-1.9.0.jar和一个aar包WaitDialog.aar(用于处理耗时等待,提醒用户,并防止用户在此期间进行新操作,直到所有分线程处理完毕,我为方便将其封装,也可以自己写)。
  3.在AndroidManifest.xml,添加权限如下:(如果是安卓10及以上(api 29),需要在application节点添加android:requestLegacyExternalStorage=“true”、 android:usesCleartextTraffic=“true”)。

<!-- 读写存储卡 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <!-- Android10新增权限MANAGE_EXTERNAL_STORAGE -->
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
    <!-- 互联网 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <!-- 查看网络状态 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

4.新建一个“权限检查的类”,代码如下:

     package com.example.scjavaweb.util;

import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Build;

import androidx.core.app.ActivityCompat;

public class PermessionUtil
{
    public static void CheckPermissions(Activity activity, String[] ArrayPermssion, int requstcode)
    {
        if (Build.VERSION.SDK_INT>=23) //安卓6以上可以动态授权
        {
            for (String pressionname:ArrayPermssion )
            {
                int permission = ActivityCompat.checkSelfPermission(activity,
                        pressionname);

                if (permission != PackageManager.PERMISSION_GRANTED) {
                    // 请求权限
                    ActivityCompat.requestPermissions(activity, ArrayPermssion,
                            requstcode);
                }
            }
        }
    }
}

5.新建一个Activity页面,在Activity对应的布局文件中添加一个按钮(布局十分简单,代码略)。
  6.在Activity对应的java页面,编写代码如下

package com.example.scjavaweb;

import androidx.appcompat.app.AppCompatActivity;

import android.Manifest;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.example.scjavaweb.util.PermessionUtil;

import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.UUID;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import swaddle.yinzhenwei.waitdialog.WaitDialog;

public class MainActivity extends AppCompatActivity implements View.OnClickListener
{
    private static String[] PERMISSIONS = {
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.MANAGE_EXTERNAL_STORAGE
    };

    private WaitDialog waitDialog;




    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        PermessionUtil.CheckPermissions(this,PERMISSIONS,1);
        setContentView(R.layout.activity_main);
        waitDialog=new WaitDialog(this);
        findViewById(R.id.Btn).setOnClickListener(this);


    }

    private ResponseBody upload(String url, String filePath, String fileName) throws Exception
    {

        OkHttpClient client = new OkHttpClient();

        RequestBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("file", fileName,
                        RequestBody.create(MediaType.parse("multipart/form-data"), new File(filePath)))
                .build();



        Request request = new Request.Builder()
                .header("Authorization", "Client-ID " + UUID.randomUUID())
                .url(url)
                .post(requestBody)
                .build();


        Response response = client.newCall(request).execute();
        if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);


        return response.body();
    }




    private void uploadtojavaweb(String UploadFilename)
    {


        Calendar calendar=Calendar.getInstance();

        Message message = Message.obtain(); // 获得一个默认的消息对象
        String ext=GetExt(UploadFilename);
        String fileName=String.valueOf(calendar.getTimeInMillis())+"."+ext;
        String url = "http://10.0.2.2:1994/firstweb/UploadHandleServlet";



        try
        {
//
            String str=upload(url, UploadFilename, fileName).string();
            Log.v("yzw",str);
            message.obj=str;


        }
        catch (Exception e)
        {
            Log.v("yzw",e.toString());
            message.obj=e.toString();

        }
        mHandler.sendMessage(message);

    }

    private void openalbum()
    {

        Intent albumIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        //albumIntent.addCategory(Intent.CATEGORY_OPENABLE);
        albumIntent.setType("image/*"); // 类型为图像

        startActivityForResult(albumIntent, 100); // 打开系统相册
    }

    private String uri2Path(Uri uri) //将URi转为路径
    {

        int actual_image_column_index;

        String img_path;

        String[] proj = { MediaStore.Images.Media.DATA };

        Cursor cursor = getContentResolver().query(uri, proj, null, null, null);


        actual_image_column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);

        cursor.moveToFirst();

        img_path = cursor.getString(actual_image_column_index);

        return img_path;

    }

    private String GetExt(String FileName) //获得扩展名
    {
        String result="";
        if (FileName.length()>0)
        {
            String[] arrext=FileName.split("\\.");
            if (arrext.length>0)
            {
                result=arrext[arrext.length-1];
            }
            else
            {
                result="";
            }
        }
        return  result;
    }

    private Handler mHandler = new Handler()
    {
        public void handleMessage(Message msg)
        {

            String tip=String.valueOf(msg.obj);
            if (tip.length()>0) {
                Toast.makeText(MainActivity.this, tip, Toast.LENGTH_LONG).show();
            }
            waitDialog.dismiss();

        }
    };


    @Override
    public void onClick(View view)
    {

        openalbum();
    }

    protected void onActivityResult(int requestCode, int resultCode, Intent intent)
    {
        super.onActivityResult(requestCode, resultCode, intent);
        switch (requestCode)
        {
            case 100:

                Uri uri = intent.getData(); // 获得已选择照片的路径对象
                String FileName=uri2Path(uri);
                TUpload tupload=new TUpload();
                tupload.FileName=FileName;
                waitDialog.show();
                waitDialog.setText("正将文件上传到服务器,稍候");
                tupload.start();
                break;

        }
    }

    private class TUpload extends Thread
    {

        public String FileName="";

        public void run()
        {
            uploadtojavaweb(FileName);
        }
    }
}

至此,安卓端的代码完成,运行之,在图库中选择一张图片上传,如果上传成功,可以在网站(api)的物理路径看到这张上传的图片。
  在编写应用端(安卓设备)代码时有以下几点需要注意。
  1.在处理网络操作等耗时,不要在主线程进行(安卓4.0后默认不允许在主线中进行耗时操作),应在分线程中进行处理。
  2.安卓分线程中不能编辑UI,但可以访问,如果要编辑UI,可以通过广播或handle.sendmessage与主线程通信,由主线程操作UI。
  3.如果AVD模拟器访问本地计算机(即AVD模拟器与服务器处于同一电脑),需要将本地ip127.0.0.1或localhost改为10,0.2.2,127.0.0.1或localhost模拟器会当做其本身。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值