直接通过HTTP上传File到服务器,并返回所需数据(传的是File,不是form表单,没有其他jar包)

本文介绍了一种通过HTTP流上传文件到服务器的方法,包括Spring MVC Controller的实现细节及常见问题解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  需求是模拟form表单,通过HTTP流上传文件到服务器,前面找了好多资料,很多是有jar包的,要不就是太复杂,或者过时的,不生效的。最后找了一个比较清晰的,但是这个也不完整,有错误。通过不断的了解,最终理解了实现的原理,并作出修改。

最初这个方法是通过servlet实现的,但现在都是用的springMVC 的Controller,内部代码也缺少一些配置。最终修改成下面这样。

//上传文件
private String upload(File file){
    String uploadFile = file.getAbsolutePath();//读取当前文件绝对路径
    String[] strs=uploadFile.split(FinalCode.IV);// 构建源文件
    String newName =strs[1].substring(1);//获取相对文件路径
    String fname=newName.substring(0,newName.lastIndexOf('\\')+1);//获取文件名
    //上面是获取文件名,有些可以不需要
    StringBuffer b = new StringBuffer();//创建Controller执行完上传返回的String
    String end = "\r\n";//上传模拟http
    String twoHyphens = "--";
    String boundary = "*****";
    String actionUrl = "http://127.0.0.1:8080/uploadServlet";//构建请求的Controller
    try {
        URL url = new URL(actionUrl);//构建URL
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setDoInput(true);//允许Input、Output,不使用Cache
        con.setDoOutput(true);
        con.setUseCaches(false);
        con.setRequestMethod("POST");//设置传送的method=POST
        con.setRequestProperty("Connection", "Keep-Alive");//setRequestProperty
        con.setRequestProperty("Charset", "UTF-8");//设置编码格式
        con.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);//设置是form请求
        DataOutputStream ds = new DataOutputStream(con.getOutputStream());//设置DataOutputStream
        ds.writeBytes(twoHyphens + boundary + end);//设置结束标记
        ds.writeBytes("Content-Disposition: form-data; " + "name=\"file1\";filename=\"" + newName + "\"" + end);
        ds.writeBytes(end);//写入结束标记
        FileInputStream fStream = new FileInputStream(uploadFile);//取得文件的FileInputStream
        int bufferSize = 1024*500;//设置每次写入500kb
        byte[] buffer = new byte[bufferSize];
        int length = -1;
        while ((length = fStream.read(buffer)) != -1) {//从文件读取数据至缓冲区
            ds.write(buffer, 0, length);//将资料写入DataOutputStream中
        }
        ds.writeBytes(end);
        ds.writeBytes(twoHyphens + boundary + twoHyphens + end);
        fStream.close();//close streams
        ds.flush();
        InputStream is = con.getInputStream();//以流的方式取得Response返回的内容
        int ch;
        while ((ch = is.read()) != -1) {
            b.append((char) ch);
        }
        ds.close();//关闭DataOutputStream
    } catch (Exception e) {
        System.out.println(("上传成功"));
    }
    return b.toString();
}

然后就是名为uploadServlet的Controller,它是在InputStream is = con.getInputStream();//以流的方式取得Response返回的内容

时会去请求这个Controller。

    @RequestMapping("/uploadServlet")
    @ResponseBody
    public String uploadServlet(HttpServletRequest request) {
        String savePath="";//设置文件在服务器绝对路径
        try {
            System.out.println("IP:" + request.getRemoteAddr());//监测IP
            DiskFileItemFactory facotry = new DiskFileItemFactory();// 1、创建工厂类:DiskFileItemFactory
            String tempDir = servletContext.getRealPath("/WEB-INF/temp");
            facotry.setSizeThreshold(10*1024*1024);//设置内存为10M,小于10M才能上传(最初没有,造成只能上传10kb)
            facotry.setRepository(new File(tempDir));//设置临时文件存放目录
            ServletFileUpload upload = new ServletFileUpload(facotry);// 2、创建核心解析类:ServletFileUpload
            upload.setHeaderEncoding("UTF-8");// 解决上传的文件名乱码
            upload.setFileSizeMax(1024 * 1024 * 10);// 单个文件上传最大值是10M
            upload.setSizeMax(1024 * 1024 * 80);//文件上传的总大小限制80M
            boolean bb = upload.isMultipartContent(request);// 3、判断用户的表单提交方式是不是multipart/form-data
            if (!bb)
                return null;
            List<FileItem> items = upload.parseRequest(request);// 4、是:解析request对象的正文内容List<FileItem>
            String storePath = servletContext.getRealPath("/WEB-INF/upload");// 上传的文件的存放目录
            for (FileItem item : items) {
                if (item.isFormField()) { // 5、判断是否是普通表单:打印看看
                    String fieldName = item.getFieldName();// 请求参数名
                    String fieldValue = item.getString("UTF-8");// 请求参数值
                    System.out.println(fieldName + "=" + fieldValue);
                } else {// 6、上传表单:得到输入流,处理上传:保存到服务器的某个目录中,保存时的文件名是啥?
                    String fileName = item.getName();// 得到上传文件的名称
                    // C:\Documents  and Settings\shc\桌面\a.txt  a.txt
                    //解决用户没有选择文件上传的情况
                    if(fileName==null||fileName.trim().equals(""))
                        continue;
                    //这里删除了获取文件夹,下面需要判断的
                    InputStream in = item.getInputStream();//获取当前文件的流
                    
                   //这里删除了验证是否存在同类型文件,每个人的功能不一样,所以你们不需要
                   //这个savePath就是在Tomcat下的绝对路径了,就是storePath(这个是服务器的地址)+(前面获取的文件夹+文件名)反正你们根据需求去获取
                    OutputStream out = new FileOutputStream(savePath);
                    byte b[] = new byte[1024*500];
                    int len = -1;
                    while ((len = in.read(b)) != -1) {
                        out.write(b, 0, len);
                    }
                    in.close();
                    out.close();
                    item.delete();//删除临时文件
                }
            }
        }catch(FileUploadBase.FileSizeLimitExceededException e){
            e.printStackTrace();
            request.setAttribute("message", "单个文件大小不能超出10M");
        }catch(FileUploadBase.SizeLimitExceededException e){
            e.printStackTrace();
            request.setAttribute("message", "总文件大小不能超出50M");
        }catch (Exception e) {
            e.printStackTrace();
            request.setAttribute("message", "上传失败");
        }
        return savePath;
    }

我传入的是文件夹,上传上去的也是同一结构,而且我还加了一些验证,修改文件名的功能。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值