HttpURLConnection上传文件及服务器端接收

一、HttpURLConnection上传文件:

(一)、 HttpURLConnection上传文件操作步骤:

    1、实例化URL对象。调用URL有参构造方法,参数是一个url地址;

    2、调用URL对象的openConnection()方法,创建HttpURLConnection对象;

    3、调用HttpURLConnection对象setDoOutput(true)、setDoInput(true)、setRequestMethod("POST");

    4、设置Http请求头信息;(Accept、Connection、Accept-Encoding、Cache-Control、Content-Type、User-Agent

    5、调用HttpURLConnection对象的connect()方法,建立与服务器的真实连接;

    6、调用HttpURLConnection对象的getOutputStream()方法构建输出流对象;

    7、设置三个常用字符串常量:换行、前缀、分界线(NEWLINE、PREFIX、BOUNDARY);

    8、获取表单中上传控件之外的控件数据,写入到输出流对象(根据HttpWatch提示的流信息拼凑字符串);

    9、获取表单中上传控件的数据,写入到输出流对象(根据HttpWatch提示的流信息拼凑字符串);

    10、调用HttpURLConnection对象的getInputStream()方法构建输入流对象;

    11、调用HttpURLConnection对象的getResponseCode()获取客户端与服务器端的连接状态码。如果是200,则执行以下操作,否则提示服务器连接异常;

    12、将输入流转成字节数组,返回给客户端。

(二)、核心代码:

public class URLConnectionTest {

        public static void main(String[] args) {
                // 指定表单提交的url地址
                String url = "http://localhost:8080/JavaServer2/UploadServlet";
                // 将上传控件之外的其他控件的数据信息存入map对象
                Map<String, String> map = new HashMap<String, String>();
                map.put("username", "test");
                map.put("password", "123456");
                // 指定要上传到服务器的文件的客户端路径
                String filePath = "d:\\a.jpg";

                // 获取到要上传的文件的输入流信息,通过ByteArrayOutputStream流转成byte[]
                BufferedInputStream bis = null;
                byte[] body_data = null;
                try {
                        bis = new BufferedInputStream(new FileInputStream(filePath));
                } catch (FileNotFoundException e) {
                        e.printStackTrace();
                }
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                int c = 0;
                byte[] buffer = new byte[8 * 1024];
                try {
                        while ((c = bis.read(buffer)) != -1) {
                                baos.write(buffer, 0, c);
                                baos.flush();
                        }
                        body_data = baos.toByteArray();
                        baos.close();
                } catch (IOException e) {
                        e.printStackTrace();
                }
                // 调用自定义的post数据方法,提交表单数据及上传文件
                String result = doPostSubmitBody(url, map, filePath, body_data, "utf-8");
                System.out.println(new String(result));
        }

        /**
         * 五个参数: 
         *  1、String url:指定表单提交的url地址 
         *  2、Map<String, String> map:将上传控件之外的其他控件的数据信息存入map对象 
         *  3、String filePath:指定要上传到服务器的文件的客户端路径
         *  4、byte[] body_data:获取到要上传的文件的输入流信息,通过ByteArrayOutputStream流转成byte[]
         *  5、String charset:设置字符集
         */
        public static String doPostSubmitBody(String url, Map<String, String> map,
                        String filePath, byte[] body_data, String charset) {
                // 设置三个常用字符串常量:换行、前缀、分界线(NEWLINE、PREFIX、BOUNDARY);
                final String NEWLINE = "\r\n";
                final String PREFIX = "--";
                final String BOUNDARY = "#";
                HttpURLConnection httpConn = null;
                BufferedInputStream bis = null;
                DataOutputStream dos = null;
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                try {
                        // 实例化URL对象。调用URL有参构造方法,参数是一个url地址;
                        URL urlObj = new URL(url);
                        // 调用URL对象的openConnection()方法,创建HttpURLConnection对象;
                        httpConn = (HttpURLConnection) urlObj.openConnection();
                        // 调用HttpURLConnection对象setDoOutput(true)、setDoInput(true)、setRequestMethod("POST");
                        httpConn.setDoInput(true);
                        httpConn.setDoOutput(true);
                        httpConn.setRequestMethod("POST");
                        // 设置Http请求头信息;(Accept、Connection、Accept-Encoding、Cache-Control、Content-Type、User-Agent)
                        httpConn.setUseCaches(false);
                        httpConn.setRequestProperty("Connection", "Keep-Alive");
                        httpConn.setRequestProperty("Accept", "*/*");
                        httpConn.setRequestProperty("Accept-Encoding", "gzip, deflate");
                        httpConn.setRequestProperty("Cache-Control", "no-cache");
                        httpConn.setRequestProperty("Content-Type",
                                        "multipart/form-data; boundary=" + BOUNDARY);
                        httpConn.setRequestProperty(
                                        "User-Agent",
                                        "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30)");
                        // 调用HttpURLConnection对象的connect()方法,建立与服务器的真实连接;
                        httpConn.connect();

                        // 调用HttpURLConnection对象的getOutputStream()方法构建输出流对象;
                        dos = new DataOutputStream(httpConn.getOutputStream());
                        // 获取表单中上传控件之外的控件数据,写入到输出流对象(根据HttpWatch提示的流信息拼凑字符串);
                        if (map != null && !map.isEmpty()) {
                                for (Map.Entry<String, String> entry : map.entrySet()) {
                                        String key = entry.getKey();
                                        String value = map.get(key);
                                        dos.writeBytes(PREFIX + BOUNDARY + NEWLINE);
                                        dos.writeBytes("Content-Disposition: form-data; "
                                                        + "name=\"" + key + "\"" + NEWLINE);
                                        dos.writeBytes(NEWLINE);
                                        dos.writeBytes(URLEncoder.encode(value.toString(), charset));
                                        // 或者写成:dos.write(value.toString().getBytes(charset));
                                        dos.writeBytes(NEWLINE);
                                }
                        }

                        // 获取表单中上传控件的数据,写入到输出流对象(根据HttpWatch提示的流信息拼凑字符串);
                        if (body_data != null && body_data.length > 0) {
                                dos.writeBytes(PREFIX + BOUNDARY + NEWLINE);
                                String fileName = filePath.substring(filePath
                                                .lastIndexOf(File.separatorChar));
                                dos.writeBytes("Content-Disposition: form-data; " + "name=\""
                                                + "uploadFile" + "\"" + "; filename=\"" + fileName
                                                + "\"" + NEWLINE);
                                dos.writeBytes(NEWLINE);
                                dos.write(body_data);
                                dos.writeBytes(NEWLINE);
                        }
                        dos.writeBytes(PREFIX + BOUNDARY + PREFIX + NEWLINE);
                        dos.flush();

                        // 调用HttpURLConnection对象的getInputStream()方法构建输入流对象;
                        byte[] buffer = new byte[8 * 1024];
                        int c = 0;
                        // 调用HttpURLConnection对象的getResponseCode()获取客户端与服务器端的连接状态码。如果是200,则执行以下操作,否则返回null;
                        if (httpConn.getResponseCode() == 200) {
                                bis = new BufferedInputStream(httpConn.getInputStream());
                                while ((c = bis.read(buffer)) != -1) {
                                        baos.write(buffer, 0, c);
                                        baos.flush();
                                }
                        }
                        // 将输入流转成字节数组,返回给客户端。
                        return new String(baos.toByteArray(), charset);
                } catch (Exception e) {
                        e.printStackTrace();
                } finally {
                        try {
                                dos.close();
                                bis.close();
                                baos.close();
                        } catch (Exception e) {
                                e.printStackTrace();
                        }
                }
                return null;
        }
}

二、、如果通过表单往服务器上传图片等文件,而服务器如何通过servlet接收并保存图片?

(一)表单的示例代码:

<html>
<head>
<meta charset="UTF-8">
<title>用户注册</title>
</head>
<body>
  <form method="post" action="UploadServlet" enctype ="multipart/form-data" >
        用户名:<input type="text" name="username"><br>
        密    码:<input type="password" name="password"><br>
        上传头像:<input type="file" name="uploadFile" /> <br/>
        <input type="submit" value="注册">
  </form>
</body>
</html>

    【重点:】当上传文件时:

    A、表单的method必须是post;

    B、必须给表单设置属性enctype ,属性值是"multipart/form-data" 。

    C、表单上传文件的input控件的type值为file。

(二)、服务器端Servlet的示例代码:

      protected void doPost(HttpServletRequest request,
                        HttpServletResponse response) throws ServletException, IOException {
                // 设置字符集
                response.setContentType("text/html;charset=utf-8");
                request.setCharacterEncoding("utf-8");
                response.setCharacterEncoding("utf-8");
                // 构建打印输出流,负责打印输出
                PrintWriter pWriter = response.getWriter();

                // 当表单中设置了enctype属性后,servlet通过getParameter接收参数会失效。
                // String name = request.getParameter("username");

                // 如果想实现上传文件,要借助以下几个类:
                // FileItem、DiskFileItemFactory、ServletFileUpload

                DiskFileItemFactory factory = new DiskFileItemFactory();
                ServletFileUpload fileUpload = new ServletFileUpload(factory);
                // 定义最大允许上传的文件尺寸
                fileUpload.setFileSizeMax(5 * 1024 * 1024);

                String username = "";
                String password = "";
                String rootPath = "";
                String urlPath = "";

                try {
                        // 获取客户端所有的表单请求数据。这些数据都被放在了request对象中。可以通过解析request对象将其中的数据一一获取出来。
                        List<FileItem> list = fileUpload.parseRequest(request);

                        // pWriter.write(list.toString());
                        // 遍历从request对象中解析出来的表单数据
                        for (FileItem item : list) {
                                // 表单控件中文件上传控件的isFormField属性为false,其它控件的isFormField属性为true
                                // 先处理非文件上传控件里的数据
                                if (item.isFormField()) {
                                        // 判断表单控件中定义的name是否和解析后request对象中的数据是否一致
                                        if (item.getFieldName().equalsIgnoreCase("username")) {
                                                username = item.getString("utf-8");
                                        }
                                        if (item.getFieldName().equalsIgnoreCase("password")) {
                                                password = item.getString();
                                        }
                                } else {// 以下开始处理文件上传控件里的数据
                                        if (item.getFieldName().equalsIgnoreCase("uploadFile")) {
                                                String originalPath = item.getName();
                                                String fileName = originalPath.substring(originalPath
                                                                .lastIndexOf(File.separatorChar) + 1);
                                                // 实现文件上传
                                                rootPath = request.getSession().getServletContext().getRealPath(File.separatorChar + "upload");
                                                File file = new File(rootPath + File.separatorChar+ fileName);
                                                try {
                                                        // 将获取到的文件写到服务器硬盘中
                                                        item.write(file);
                                                } catch (Exception e) {
                                                        e.printStackTrace();
                                                }
                                                urlPath = "http://localhost:8080/JavaServer2/upload/" + fileName;
                                                pWriter.write("您的注册信息是:<br/>");
                                                pWriter.write("用户名:" + username + "<br/>");
                                                pWriter.write("密码:" + password + "<br/>");
                                                pWriter.write("头像地址为:");
                                                pWriter.write("<a href='" + urlPath + "'>" + urlPath + "</a>");
                                        }
                                }
                        }
                } catch (FileUploadException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
        }

【备注:】Tomcat服务器的真实路径:

D:\java_webapp\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps

说明:D:\java_webapp是eclipse的工作空间的目录。

猜你喜欢

转载自blog.csdn.net/dubo_csdn/article/details/86488989
今日推荐