关于上传文件,首先我的第一个案例是一个文本文件的上传,简单容易上手!
首先我们上传文件肯定就属于实体内容部分了;所以不能过GET方式请求了,要通过POST方式请求;
因为:
1.get方式是URL传值,URL长度是有限的,很短,并且实体内容只能通过POST传递;因为只有POST方式才有content-type属性。
2.因为是实体内容,所以不能通过getParameter这么草率没脑子的步骤去得到上传文件的内容了,要通过获得request的InputStream来得到实体内容:(插播一个,在序列化的时候之后,网络传输对象我之前没有思路,这里看来也应该通过流的方式)。
其次:
1.我们要注意的是上传也是一个input标签,表单上传,但是type就是填写file(当我们点击这个file类型的input的时候,就会自动弹出选择文件的窗口)。
2.我们还要注意,form中其实是可以设置加密的类型格式:entype;
默认是这么一个玩意儿:entype="application/x-www-form-urlencoded"
但是这样的话只会以键值对的方式传上文件的名字,在浏览器的开发者模式下就可以查看到,很尴尬!
所以我们要把entype修改为:multipart/form-data;
修改之后,就可以看到长度变长了:并且可用看到实际传入了值;
长度变长了:
content-type有了实际的值:
实际查看也可以看到POST请求带到服务器的内容:
首先贴jsp中的显示层的代码:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>文件上传 <%-- 在浏览器的开发模式下查看: 使用get方式的时候 实体部分没有内容 使用post方式的时候 实体部分有了内容 文件属于实体内容, 不能通过URL进行传递,只能通过POST 所以不能用GET方式请求 发现我点击上传之后,上传的不是内容 而是name和value的键值对:attachment=java8混合模式.txt 【诸如此类的】 原因就是form中的enctype影响的! enctype="application/x-www-form-urlencoded" 要修改编码类型: multipart/form-data 从键值对变成了: multipart/form-data; boundary=----WebKitFormBoundary9qkZBbwklcwsP0yC --%> <%--
servlet中处理的逻辑代码:
package upload;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileWriter;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * 模拟服务器处理上传过来的文件(手动解析文件的内容) * @author mzy * */public class UpLoadDemo01 extends HttpServlet { private static final long serialVersionUID = -6589048171165363182L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1) 获取实体 内容 InputStream in = request.getInputStream(); // 包装成BufferdReader来简化操作! BufferedReader br = new BufferedReader(new InputStreamReader(in)); // 读取一行 /* * 回忆: * 在POST中的实体内容中查看; * 我们发现,其中的实体内容中在文件内容的 * 开始和结束的时候,都有一段分割符 * 在火狐中开发模式下抓到的实体内容如下: * -----------------------------41184676334 * Content-Disposition: form-data; name="attachment"; filename="mzy_test_attach.txt" * Content-Type: text/plain * * aaa * bbb * ccc * * hello world!!! * -----------------------------41184676334-- */ // 读第一行:文件开始的分隔符:将开始分隔符保存起来 // 为什么呢? // 因为我们可以从上面的实体内容中看到: // 结束符号就比开始符号最后多两根横杠(我们就可以定位到结束位置) String fileTag = br.readLine(); // 读第二行:第二行就是文件的名称了 String str = br.readLine(); // 获取文件的名称: // 在下觉得这个获取文件名称很精彩! // System.out.println(str); String fileName = str.substring(str.indexOf("filename=\"")+10, str.length()-1); /* * 但是上面的fileName: * 最终截取出来的名字要注意; * 在火狐或者chrome内核中,只有文件名! * 但是在IE中包含着文件在客户端上的物理路径信息; * 所以如果是IE的话还要再次截取! */ if(fileName.contains("\\")) { // System.out.println(fileName); fileName = fileName.substring(fileName.lastIndexOf("\\")+1, fileName.length()); } // 之后需要跳过两行无用行: // 1.第一行是读取的格式的声明Content-Type; // 2.第二行是正文开始之前的空行(默认会加一个空行) br.readLine(); br.readLine(); // 正式开始读取文件的正文内容 String content = null; // new 一个writer将用户上传的文件写入到我的服务器的盘符上 BufferedWriter bw = new BufferedWriter(new FileWriter("e:/"+fileName)); while((content=br.readLine()) != null) { // 写出到服务器上:遇到结束符号结束 if(content.equals(fileTag+"--")) { break; // continue; 都可以 } bw.write(content); bw.newLine(); // 换行 bw.flush(); } bw.close(); br.close(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); /* * 我今天傻逼了在doPost中调用doPost,恩?恩?恩?是个傻子。 * doPost(request, response); */ doGet(request, response); }}