后端开发--之文件上传

前言:

根据工程与学习的需要,最近接触了文件上传的相关知识,一开始由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

posted @ 2017-04-09 21:30  华不摇曳  阅读(2990)  评论(0编辑  收藏  举报