后端開發--之文件上傳


前言:

根據工程與學習的需要,最近接觸了文件上傳的相關知識,一開始由android端使用volley上傳,遇到點問題,最后換成了OKhttp,服務器端采用spring MVC和flask,都成功了,將我的學習歷程記錄下來,為了更好的分享。

正文:

一、Spring MVC文件上傳

在Intellij IDEA下開發,確實新的編輯器用起來方便許多,具體的安裝我也是按照網上的教程來搭建環境的,搭建過程比較簡單,以下是我搭建成功的教程:是個系列教程:

       Intellij搭建

需要自己下載tomcat,我使用它系統的tomcat報錯了,所以改為自己的tomcat,maven也需要自己配置,系統的也遇到了問題,搭建好后運行第一個web程序,測試完成。

下面開始文件上傳的工作,首先需要在maven的pom.xml中引入要文件傳輸的包:

<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.5</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.liferay/org.apache.commons.fileupload -->
    <dependency>
      <groupId>com.liferay</groupId>
      <artifactId>org.apache.commons.fileupload</artifactId>
      <version>1.2.2.LIFERAY-PATCHED-1</version>
    </dependency>

然后修改dispatcher里的加上支持文件的配置:

 <!-- 支持上傳文件 -->  
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>  

我的dispatcher完整代碼如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--指明 controller 所在包,並掃描其中的注解-->
    <context:component-scan base-package="com.controller"/>

    <!-- 靜態資源(js、image等)的訪問 -->
    <mvc:default-servlet-handler/>

    <!-- 開啟注解 -->
    <mvc:annotation-driven/>

    <!--ViewResolver 視圖解析器-->
    <!--用於支持Servlet、JSP視圖解析-->
    <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
</beans>
View Code

然后編寫控制器代碼,使用注解的方式指定url,請求方式,和報頭的格式,具體的代碼如下:

/**
 * Created by Y-GH on 2017/4/5.
 */

// 注解標注此類為springmvc的controller,url映射為"/home"
@Controller
@RequestMapping("/home")
public class HomeController {
    //添加一個日志器
    private static final Logger logger = LoggerFactory.getLogger(HomeController.class);

    //映射一個action
    @RequestMapping(value="/upload",method=RequestMethod.POST,headers = "Accept=application/octet-stream")
    public  String upload(HttpServletRequest request, HttpServletResponse response, @RequestParam("file") MultipartFile file) throws Exception{
        //輸出日志文件

        System.out.println("upload begin");
        logger.info("the first jsp pages");
        JSONObject object = new JSONObject();
        //返回一個index.jsp這個視圖
        //如果文件不為空,寫入上傳路徑
        if(!file.isEmpty()) {
            //上傳文件路徑
            System.out.println("開始");
            String path = request.getSession().getServletContext().getRealPath("upload");
//            String path = request.getSession().getServletContext().getRealPath("/images/");
            //上傳文件名
            String filename = file.getOriginalFilename();
            File filepath = new File(path,filename);
            //判斷路徑是否存在,如果不存在就創建一個
            if (!filepath.getParentFile().exists()) {
                filepath.getParentFile().mkdirs();
            }
            //將上傳文件保存到一個目標文件當中
            file.transferTo(new File(path + File.separator + filename));

            object.put("results", "success");
            return "success";
        } else {
            object.put("results", "error");
            return "error";
        }
       
    }
}

使用MultipartFile上傳文件,很輕松就實現了,android端的代碼最后貼。

二、使用flask上傳文件

flask上傳文件只需要幾行代碼,更加方便,代碼如下:

import json
from flask import Flask
from flask import request
from flask import redirect
from flask import jsonify
app = Flask(__name__)

@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        f = request.files['file']
        f.save('/home/ygh/flask/img_card.jpg')
        data = '{"result":"sucess"}'
        result = json.loads(data)
        return json.dumps(result)
    else:
        return "error"

if __name__ == '__main__':
    app.run(host='0.0.0.0')

指定url后,判斷是否是post請求,是post請求只需要將request的文件取出即可,然后使用save保存到指定的目錄下,然后向客戶端返回json格式的結果。

這里的文件請求都沒有使用數據庫,使用數據庫只需要將文件名和路徑存入數據表中,下次取地址后,直接遍歷取出文件即可。

 

-------------------------------------------------------------------------------------------------

接下來我把android客戶端的OKhttp下的請求代碼也貼出來,方便參考:

首先引入Okhttp的依賴:

compile 'com.squareup.okhttp:okhttp:2.4.0'
compile 'com.squareup.okio:okio:1.5.0'

然后在java中實現即可,還沒有來得及進行封裝,用的原生的方式:

//首先在主線程的onCreate或onActivityResult開啟線程:
  new Thread(this).start();

//然后重寫系統回掉方法,
//注意 MainActivity extends AppCompatActivity implements Runnable
@Override
    public void run() {
        try {
            PostFile(imgPath);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

  //上傳方法  集成了okhttp
    private void PostFile(String imgPath) throws IOException, JSONException {
        File file = new File(imgPath);
        if (!file.exists())
        {
            Toast.makeText(MainActivity.this, "文件不存在,請修改文件路徑", Toast.LENGTH_SHORT).show();
            return;
        }
  //開始找到路徑放入請求體內
        RequestBody body = new MultipartBuilder()
                .addFormDataPart("file",imgPath , RequestBody.create(MediaType.parse("media/type"), new File(imgPath)))
                .type(MultipartBuilder.FORM)
                .build();
   //建立請求
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();

        OkHttpClient client = new OkHttpClient();
        Response response = client.newCall(request).execute();//發送請求
        String tempResponse =  response.body().string();
        Log.e("==返回結果==","---"+tempResponse);
        JSONArray arr = new JSONArray(tempResponse);
        String responsew = arr.getString(0);
        JSONObject obj = new JSONObject(responsew);
        result = obj.getString("result");
        Log.e("==輸出==","--"+result);
        if(result.equals("sucess")){
            JSONObject obj2 = new JSONObject(obj.getString("response"));
            Log.e("==response==","------"+obj.getString("response"));
            String day = obj2.getString("day");
            Log.e("---day---","==>"+day);
            mHandler.sendEmptyMessage(0);
        }else if(result.equals("error")){
            Log.e("==返回==","---出錯---");
            mHandler.sendEmptyMessage(1);
        }

    }

   //根據返回結果執行mHandler相應傳入處理消息的方式
    private Handler mHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {

            switch (msg.what) {
                case 0:
                    dialog.cancel();
                    Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
                    break;
                case 1:
                    dialog.cancel();
                    Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
                    break;
            }
        };
    };

至此,完成了文件上傳的基本功能,后續有新的方法會及時補充。

                                            by  STILL


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM