java与servlet以及java与php完成文件的上传

来源:互联网 发布:惊艳的句子 知乎 编辑:程序博客网 时间:2024/04/29 20:53

看了晚上很多的有关java与servlet文件上传的例子,不过似乎都是说上传后的文件损坏,自己亲自尝试了一下,上传后的图片却是打不开,查看了一下文件的大小,发现上传后的文件变大了.自己查看代码,发现是客户端提交时写入了多余的信息到字节流中,可以在服务器端进行处理,下面是在客户端对上传字节流进行简化后的代码,上传成功.

java与servlet

客户端:

package cn.edu.ustc.file;import java.io.DataOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import java.util.UUID;public class UploadFileToServlet {private static final int TIME_OUT = 10 * 10000000; // 超时时间private static final String CHARSET = "utf-8"; // 设置编码public static boolean uploadFile(File file) {String BOUNDARY = UUID.randomUUID().toString(); // 边界标识 随机生成String CONTENT_TYPE = "multipart/form-data"; // 内容类型String RequestURL = "http://127.0.0.1:8080/Honest/ReceiveFile?file_name=zhangsanfeng.png";try {URL url = new URL(RequestURL);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setReadTimeout(TIME_OUT);conn.setConnectTimeout(TIME_OUT);conn.setDoInput(true); // 允许输入流conn.setDoOutput(true); // 允许输出流conn.setUseCaches(false); // 不允许使用缓存conn.setRequestMethod("POST"); // 请求方式conn.setRequestProperty("Charset", CHARSET); // 设置编码conn.setRequestProperty("connection", "keep-alive");conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary="+ BOUNDARY);if (file != null) {/** * 当文件不为空,把文件包装并且上传 */OutputStream outputSteam = conn.getOutputStream();DataOutputStream dos = new DataOutputStream(outputSteam);InputStream is = new FileInputStream(file);byte[] bytes = new byte[1024];int len = 0;while ((len = is.read(bytes)) != -1) {dos.write(bytes, 0, len);}is.close();/** * 获取响应码 200=成功 当响应成功,获取响应的流 */int res = conn.getResponseCode();if (res == 200) {return true;}}} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return false;}public static void main(String[] args) {File file = new File("/dir/header.png");boolean res = uploadFile(file);System.out.println(res);}}
仅仅将文件流post方式写入就行了.写入地址可以加一些参数(等价于get)来传递一些参数,当然完全可以自己将所有信息全部放到字节流中.

下面是服务器端

package cn.edu.ustc.servlet;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.ServletInputStream;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * 接收文件 */@WebServlet("/ReceiveFile")public class ReceiveFile extends HttpServlet {private static final long serialVersionUID = 1L;public ReceiveFile() {super();}protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {}protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {System.out.println(request.getRequestURL());String fileName = request.getParameter("file_name");System.out.println(fileName);ServletInputStream in = request.getInputStream();byte[] buffer = new byte[1024];File file = new File(request.getSession().getServletContext().getRealPath("/img/"), fileName);FileOutputStream out = new FileOutputStream(file);int len = in.read(buffer, 0, 1024);int sum = 0;while (len != -1) {out.write(buffer, 0, len);len = in.read(buffer, 0, 1024);sum+=len;}System.out.println(sum);out.close();in.close();}}

这样就将文件放置在img文件夹了.


java与php

php上传文件中需要一些标示,也是增加了这些标示造成用servlet接收文件时文件大小增加了.

客户端:

package cn.edu.ustc.file;import java.io.DataOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import java.util.UUID;public class UploadFileToPhp {private static final int TIME_OUT = 10 * 10000000; // 超时时间private static final String CHARSET = "utf-8"; // 设置编码public static boolean uploadFile(File file) {String BOUNDARY = UUID.randomUUID().toString(); // 边界标识 随机生成String PREFIX = "--", LINE_END = "\r\n";String CONTENT_TYPE = "multipart/form-data"; // 内容类型String RequestURL = "http://127.0.0.1/php/file/upload_file_from_java.php?file_name=zhangsanfeng.png";System.out.println(RequestURL);try {URL url = new URL(RequestURL);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setReadTimeout(TIME_OUT);conn.setConnectTimeout(TIME_OUT);conn.setDoInput(true); // 允许输入流conn.setDoOutput(true); // 允许输出流conn.setUseCaches(false); // 不允许使用缓存conn.setRequestMethod("POST"); // 请求方式conn.setRequestProperty("Charset", CHARSET); // 设置编码conn.setRequestProperty("connection", "keep-alive");conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary="+ BOUNDARY);if (file != null) {/** * 当文件不为空,把文件包装并且上传 */OutputStream outputSteam = conn.getOutputStream();DataOutputStream dos = new DataOutputStream(outputSteam);StringBuffer sb = new StringBuffer();sb.append(PREFIX);sb.append(BOUNDARY);sb.append(LINE_END);/** * 这里重点注意: name里面的值为服务器端需要key(php里面需要是file),只有这个key才可以得到对应的文件 * filename是文件的名字,包含后缀名的 比如:abc.png,可以看到下面在开始与结束都写入了一些分隔符等标示. */sb.append("Content-Disposition: form-data; name=\"file\"; filename=\""+ file.getName() + "\"" + LINE_END);sb.append("Content-Type: application/octet-stream; charset="+ CHARSET + LINE_END);sb.append(LINE_END);dos.write(sb.toString().getBytes());InputStream is = new FileInputStream(file);byte[] bytes = new byte[1024];int len = 0;while ((len = is.read(bytes)) != -1) {dos.write(bytes, 0, len);}is.close();dos.write(LINE_END.getBytes());byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END).getBytes();dos.write(end_data);dos.flush();/** * 获取响应码 200=成功 当响应成功,获取响应的流 */int res = conn.getResponseCode();System.out.println(res);if (res == 200) {return true;}}} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return false;}public static void main(String[] args) {File file = new File("/dir/header.png");boolean res = uploadFile(file);System.out.println(res);}}

客户端向服务器端写入时多了一些标示.


php服务端

<?php$file_name = $_GET ['file_name'];$target_path = "/dir/img/"; // 接收文件目录,请确保相应权限问题$target_path = $target_path . $file_name;if (move_uploaded_file ( $_FILES ['file'] ['tmp_name'], $target_path )) {echo "The file " . basename ( $_FILES ['uploadedfile'] ['name'] ) . " has been uploaded";} else {echo "There was an error uploading the file, please try again!" . $_FILES ['file'] ['error'];}?>  


有关get与post参数共同使用的说明可以参考此篇文章http://blog.csdn.net/dliyuedong/article/details/38173611 .


0 0
原创粉丝点击