a) 使用的工具包,io、apache Commons fileUpload包
b) 官方使用方法介绍http://commons.apache.org/proper/commons-fileupload/using.html,通过官方的简介,我们可以直接得到一个list,所以只要大家知道怎么处理fileItem就可以了。
c) Fileupload方法简介à它是通过创建一个ServletFileUpload静态类来解析一个request的,通过静态类可以创建FileItemFactory工厂,工厂会对mulitipart类中的表单字段进行处理,不仅仅只有file字段会被处理,其余的非表单字段也会得到处理,每一个字段都将保存在一个fileitem里面,也就是一个基本的表单字段是一个fileitem,一个上传文件时一个fileitem,我们可以通过getname来获取非file字段的基本表单数据的名字,当然我们也可以通过getString来得到非表单数据的内容,最重要的就是我们可以通过isFormField来判断是否是基本的表单数据。
d) Fileupload的使用方法
i. 在html文件的表单中申明所要传输的内容文件为多部分表单数据enctype=”multipart/form-data”,其中的enctype是文件编码,它有三个值,默认值是application/x-www-form-urlencodedà在发送前编码所有的字符,multipart/form-dataà不对字符进行编码,使用文件上传的时候必须使用该值,text/plainà只实现将空格转换为+,其余的字符不进行编码。
ii. 调用ServletFileUpload.ismultipartcontent(request)来判断所得到的内容是否是一个多表单内容,如果是就做以下处理,如果不是就调用简单的post处理
iii. 创建一个DiskFileItemFactory,通过这个类,我们可以将消息中的每一个实体封装成为一个单独的DiskFileItem(FileItem接口的实现)
iv. 创建我们的ServletFileUpload,将我们的factory传入进去,这样我们的解析器就做好了
v. 通过我们的servletfileupload,我们可以调用它的parserequest(request)来解析一个请求,从而我们可以获得一个list
vi. 创建一个迭代器,开始遍历我们的list
vii. 我们从我们的list中取出每一项数据,然后对它进行判断,判断它是否是基本的表单数据isformfield,如果是,我们就通过getfiledname()获取基本表单的名字,然后可以通过这个名字来调用getString,从而获得该基本表单的值。如果不是,就说明它是一个文件表单,那么我们就调用它的write方法,将它保存到我们的文件中去。
e) 错误提醒
i. 当你在非isfieldform中获取数据的时候,如果里面的任何语句都没有执行的话,检查你的form表单中有没有给名字,对于没有给名字的内容,它是不会处理的,也就是说相当于没有接受过任何的东西,而且通过getname,我们得到的是我们上传文件的完整路径,我们可以通过String的特性将它解析出来。
二、 文件上传—HTTClient方式
a) 文件上传的方式除了上述的还有一种叫做httpclient的方式,它其实就是将上面的处理方式进行封装,但是它解决了上面那种方式不能传很大文件的局限。所以在文件上传方面推荐使用它
b) HTTPClient简介
→通过HTTPClient,我们可以获取一个网页内容,这是它的基础用法
//将联网的对象创建出来,相当于打开浏览器 HttpClient client=new HttpClient(); //相当于输入网址 HttpMethod method=new PostMethod("http://localhost:8080/login/login.jsp"); try { //由client解析这个method,后面的处理都交由method去做,而非我们的client client.executeMethod(method); //获取状态联网字 System.out.println(method.getStatusLine()); //这一段话将会将网页中的httpclient源码全部打印出来 System.out.println(method.getResponseBodyAsString()); //使用完之后一定要记得释放资源,将我们的method释放掉 method.releaseConnection(); //释放链接 } catch (Exception e) { e.printStackTrace(); } } |
→往服务器发送用户名和age
public static void main(String[] args) { HttpClient client=new HttpClient(); HttpMethod method=getpost(); try { client.executeMethod(method); //打印返回的头文件,同时也承担着发送的任务 System.out.println(method.getStatusLine()); //打印返回的内容 System.out.println(method.getResponseBodyAsString().getBytes("8859_1")); }catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static PostMethod getpost(){ PostMethod method=new PostMethod("http://localhost:8080/login2/servlet/login"); NameValuePair s=new NameValuePair("name","zhangsan"); NameValuePair s2=new NameValuePair("age","12"); method.setRequestBody(new NameValuePair[]{s,s2}); return method; } |
→往服务器发送文件,往服务器发送文件采用的是一种新定义的类,MultipartPostMethod,然后给这个方法指明需要传递的参数,当然你在这个参数的书写上可以写文件,也可以写路径,同时你还的通过client写超时时间。网上很多教程都写着超时时间是getparams来实现,但是现在已经实现不了了,可以通过client来实现。
public static void main(String[] args) { HttpClient client=new HttpClient(); try{ MultipartPostMethod method=new MultipartPostMethod("http://172.28.132.135:8080/login3/servlet/myservlet"); method.addParameter("up",new File("c://httpwatchpro.exe")); //不能设置超时时间 //跟网上的有差异,在这里我没有通过client获得manager,然后设置,因为我的导不出来,所以就直接通过client进行设置 client.setTimeout(5000); int ret=client.executeMethod(method); //System.out.println("返回值是"+ret); }catch(Exception e){ e.printStackTrace(); } } |
三、 Android实现文件上传
a) 跟上面的第三个client类似,模拟操作即可,只是记得要添加权限和相应的包,不要采用android自带的client包,因为那个包是不支持文件上传的。
四、 问题分析
a) 不出内容,也没看到任何错误
i. 可能是你在一个类中打印遮盖了tomcat打印的数据,你可以将你类中的打印去掉,查看tomcat控制台的打印
b) 不能调用method.getparams.settimeout
i. 你可以不选用这种方式,其实这句话可有可无,你心里明白就行,不然你可以使用httpclient.settimeout来设置最大超时时间,效果也是一样的
同时,这相当于一个模版类,大家也无需多记,只要大致知道每个字段的意思就可以了,下次对着模版可以敲出来就可以了。