前端使用c# winform创建客户端来进行post发送文件,后台使用java来接收
需求:1、前台通过c# 来上传参数及文件; 2、后台通过java编写服务器端代码来接收;
分析:
一、针对1,有很多方式来进行传输,比如Ftp方式,HttpWebRequest方式等,我们这里使用HttpWebRequest方式来进行post请求。
二、针对2,我使用commons-fileupload-1.2.1.jar来进行文件接收。
代码:
1、前端代码:
1 // 拼接上传远程服务器路径 2 string url = serverAddress + "/fileupload/upload"; 3 4 // 拼接同文件一同上传的表单文本域及值(即传入的参数) 5 NameValueCollection nvc = new NameValueCollection(); 6 nvc.Add("templateId", templateId); // 传入概预算工程ID参数 7 8 StringBuilder sb = new StringBuilder(); 9 string boundary = "----------------" + DateTime.Now.Ticks.ToString("x"); // 边界符 10 11 HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url); // 由于HttpWebRequest没有提供属性来方便传参,所以下面我们只能自己模拟传参 12 httpWebRequest.ContentType = "multipart/form-data; boundary=" + boundary; // 声明数据类型 13 httpWebRequest.Method = "POST"; 14 httpWebRequest.KeepAlive = true; 15 httpWebRequest.Credentials = System.Net.CredentialCache.DefaultCredentials; 16 17 Stream memStream = new System.IO.MemoryStream(); 18 19 string formdataTemplate = "\r\n--" + boundary + "\r\nContent-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}"; // key就是{0},value是{1} 20 foreach (string key in nvc.Keys) 21 { 22 string formitem = string.Format(formdataTemplate, key, nvc[key]); 23 sb.Append(formitem); 24 byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem); 25 memStream.Write(formitembytes, 0, formitembytes.Length); 26 } 27 28 // 这里key是{0},value是{1} 29 string headerTemplate = "\r\n--" + boundary + "\r\nContent-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: application/octet-stream\r\n\r\n"; 30 31 // 逐个将文件内容写入流 32 for (int i = 0; i < files.Length; i++) 33 { 34 FileInfo fi = new FileInfo(files[i]); 35 36 // 写入文件开始标记 37 string header = string.Format(headerTemplate, "file", fi.Name); 38 sb.Append(header); 39 byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header); 40 memStream.Write(headerbytes, 0, headerbytes.Length); 41 42 FileStream fileStream = new FileStream(fi.FullName, FileMode.Open, FileAccess.Read); 43 44 byte[] buffer = new byte[1024 * 8];//每次上传8M 45 46 int bytesRead = 0; 47 // 写入文件内容 48 while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) 49 { 50 memStream.Write(buffer, 0, bytesRead); 51 } 52 fileStream.Close(); 53 } 54 sb.Append("\r\n--" + boundary + "--\r\n"); 55 // 将结束标记写入内存流 56 byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n"); 57 memStream.Write(boundarybytes, 0, boundarybytes.Length); 58 59 httpWebRequest.ContentLength = memStream.Length;//流总大小 60 61 Stream requestStream = httpWebRequest.GetRequestStream(); 62 63 memStream.Position = 0; 64 byte[] tempBuffer = new byte[memStream.Length]; 65 memStream.Read(tempBuffer, 0, tempBuffer.Length); 66 memStream.Close(); 67 requestStream.Write(tempBuffer, 0, tempBuffer.Length); 68 requestStream.Close(); 69 70 WebResponse webResponse = httpWebRequest.GetResponse(); 71 Stream stream = webResponse.GetResponseStream(); 72 StreamReader reader = new StreamReader(stream); 73 string ret = reader.ReadToEnd(); 74 75 return ret;
2、后台代码:(这里是借鉴bire)你写的代码,稍作修改了下)
1 //获得磁盘文件条目工厂 2 DiskFileItemFactory factory = new DiskFileItemFactory(); 3 //获取文件需要上传到的路径 4 String path = request.getRealPath("/upload"); 5 6 //如果没以下两行设置的话,上传大的 文件 会占用 很多内存, 7 //设置暂时存放的 存储室 , 这个存储室,可以和 最终存储文件 的目录不同 8 /** 9 * 原理 它是先存到 暂时存储室,然后在真正写到 对应目录的硬盘上, 10 * 按理来说 当上传一个文件时,其实是上传了两份,第一个是以 .tem 格式的 11 * 然后再将其真正写到 对应目录的硬盘上 12 */ 13 factory.setRepository(new File(path)); 14 //设置 缓存的大小,当上传文件的容量超过该缓存时,直接放到 暂时存储室 15 factory.setSizeThreshold(1024*1024) ; 16 17 //高水平的API文件上传处理 18 ServletFileUpload upload = new ServletFileUpload(factory); 19 20 21 try { 22 //可以上传多个文件 23 List<FileItem> list = (List<FileItem>)upload.parseRequest(request); 24 25 for(FileItem item : list) 26 { 27 //获取表单的属性名字 28 String name = item.getFieldName(); 29 30 //如果获取的 表单信息是普通的 文本 信息 31 if(item.isFormField()) 32 { 33 //获取用户具体输入的字符串 ,名字起得挺好,因为表单提交过来的是 字符串类型的 34 String value = item.getString() ; 35 36 request.setAttribute(name, value); 37 } 38 //对传入的非 简单的字符串进行处理 ,比如说二进制的 图片,电影这些 39 else 40 { 41 /** 42 * 以下三步,主要获取 上传文件的名字 43 */ 44 //获取路径名 45 String value = item.getName() ; 46 //索引到最后一个反斜杠 47 int start = value.lastIndexOf("\\"); 48 //截取 上传文件的 字符串名字,加1是 去掉反斜杠, 49 String filename = value.substring(start+1); 50 51 request.setAttribute(name, filename); 52 53 //真正写到磁盘上 54 //它抛出的异常 用exception 捕捉 55 56 //item.write( new File(path,filename) );//第三方提供的 57 58 //手动写的 59 OutputStream out = new FileOutputStream(new File(path,filename)); 60 61 InputStream in = item.getInputStream() ; 62 63 int length = 0 ; 64 byte [] buf = new byte[1024] ; 65 66 System.out.println("获取上传文件的总共的容量:"+item.getSize()); 67 68 // in.read(buf) 每次读到的数据存放在 buf 数组中 69 while( (length = in.read(buf) ) != -1) 70 { 71 //在 buf 数组中 取出数据 写到 (输出流)磁盘上 72 out.write(buf, 0, length); 73 74 } 75 76 in.close(); 77 out.close(); 78 79 // 将上传后的文件信息保存到表t_template_style 80 TemplateStyle templateStyle = new TemplateStyle(); 81 templateStyle.setFilePath(path+"\\"+filename); 82 templateStyle.setTemplateId(Integer.parseInt(request.getAttribute("templateId").toString())); 83 templateStyleService.save(templateStyle); 84 85 } 86 } 87 88 return null; 89 90 }catch (Exception e) { 91 resString = "error"; 92 e.printStackTrace(); 93 return null; 94 }finally{ 95 response.getWriter().write(resString); 96 }