• 后端开发--之文件上传


    前言:

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

  • 相关阅读:
    JAVA中的注解小结
    终结任务
    共享资源访问
    基本线程机制
    HashSet、LinkedHashSet、TreeSet
    EnumMap
    LinkedHashMap及其源码分析
    集合迭代器快速失败行为及CopyOnWriteArrayList
    LinkedList
    比特币中的Base58 编码
  • 原文地址:https://www.cnblogs.com/ygh1229/p/6686517.html
Copyright © 2020-2023  润新知