// 文件路径 D:\ApacheServer\web_java\HelloWorld\src\com\test\TestServletForm.java
package com.test; import java.io.File;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.filefilter.SuffixFileFilter; public class TestServletForm { public void testfun(HttpServletRequest request){
// 检测是 GET 和 x-www-form-urlencode POST 还是 multipart/form-data POST 方式
if (!ServletFileUpload.isMultipartContent(request)) {
// 提交的表单类型为GET 或者 x-www-form-urlencoded 方式的 POST
getOrFormUrlencoded(request);
}else {
// 提交的表单类型为 multipart/form-data 的 POST
formData(request);
}
} // 自建方法,用来处理 GET URL 或者 application/x-www-form-urlencoded 方式的 POST
public void getOrFormUrlencoded(HttpServletRequest request){ // getParameter,getParameterNames 只能获取 get 参数(POST 请求里也能用 getParameter 获取 GET 参数)或者编码格式为 application/x-www-form-urlencoded 的 post 数据,无法获取 multipart/form-data 的 post 数据
// application/x-www-form-urlencoded 传的 post 数据实际和 get 方式一样,都是格式化成 参数1=值1&参数2=值2&参数3=值3&... ,区别是 get 参数在 url 中,post 参数在请求体里。
String name_val = request.getParameter("name");
System.out.println("表单名 : name 单一值为 : " + name_val); // getParameterNames() 方法获取所有提交的表单参数名。该方法返回一个枚举对象,包含未指定顺序的参数名
Enumeration paramNames = request.getParameterNames();
// hasMoreElements() 循环遍历判断该枚举是否有更多元素,指针每次往后移一位
while(paramNames.hasMoreElements()) {
// nextElement() 每次获取该枚举一个元素,指针每次往后移一位
String paramName = (String)paramNames.nextElement();
// 根据参数名获取对应参数值,但不知道该参数名对应单个值还是多个值(复选框即是多个表单同名,不同值,与PHP不同JAVA相同复选框名后面不用加中括号 [] ),所以用数组接收
String paramValues[] = request.getParameterValues(paramName);
// 读取参数值的数据
if (paramValues.length == 1) { // 该参数名对应单一参数值
// 参数值为 paramValues[0]
String paramValue = paramValues[0];
if (paramValue.length() > 0) { // 判断该参数值有实际字符串内容
System.out.println("表单名 : " + paramName + "单一值为 : " + paramValue);
}
} else {
// 读取多个值的数据
for(int i=0; i < paramValues.length; i++) {
// 值为 paramValues[i]
System.out.println("多重参数名 : " + paramName + "多重id值 : "+i+"为 : " + paramValues[i]);
}
}
}
}
// 自建方法,用来处理 multipart/form-data 方式的 POST
// 获取 form-data 类型 post 数据依赖于 FileUpload,下载地址 http://commons.apache.org/proper/commons-fileupload/ 这里用到的是 FileUpload 1.4 选择 Binaries->commons-fileupload-1.4-bin.zip
// FileUpload 依赖于 Commons IO,下载地址 http://commons.apache.org/proper/commons-io/ 这里用到的是 Commons IO 2.6 选择 Binaries->commons-io-2.6-bin.zip
// 将下载的压缩包内的 commons-io-2.6.jar 和 commons-fileupload-1.4.jar 解压缩到 D:\ApacheServer\web_java\HelloWorld\WebContent\WEB-INF\lib 中。环境变量 CLASSPATH 补充 ";D:\ApacheServer\web_java\HelloWorld\WebContent\WEB-INF\lib\commons-io-2.6.jar;D:\ApacheServer\web_java\HelloWorld\WebContent\WEB-INF\lib\commons-fileupload-1.4.jar;" 。eclipse->Java Build Path 中分别引入 commons-io-2.6.jar 与 commons-fileupload-1.4.jar
public void formData(HttpServletRequest request){
try {
// 创建磁盘文件项目工厂(form-data方式POST获取参数必须用的不管有无上传文件),可设置限制上传文件的临时存储目录等
DiskFileItemFactory factory = new DiskFileItemFactory(); // 可有可无,setSizeThreshold方法判断post数据(包括上传文件及表单数据)的大小(以字节为单位的int值,大于该值则post数据以临时文件形式存在磁盘,小于等于此值则存在内存中),如果从没有调用该方法设置此临界值,将会采用系统默认值10KB。对应的getSizeThreshold() 方法用来获取此临界值。
//factory.setSizeThreshold(1024 * 1024 * 3); // 3MB // 可有可无,设置当上传数据大于 setSizeThreshold 设置的值时,临时文件在磁盘上的存放目录。当从没有此方法设置临时文件存储目录时,采用系统默认的临时文件路径 Tomcat 系统默认临时目录为 tomcat安装目录/temp/,默认的临时文件路径可通过 System.getProperty("java.io.tmpdir");查看
//factory.setRepository(new File(System.getProperty("java.io.tmpdir"))); // 通过文件工厂对象创建上传对象,可设置 post 文件最大上传大小,请求数据最大值(包含文件和表单数据)等
ServletFileUpload upload = new ServletFileUpload(factory); // 可有可无,设置上传的单个文件的最大字节数为100M
//upload.setFileSizeMax(1024 * 1024 * 100); // 可有可无,设置整个表单的最大字节数为1G (包含文件和表单数据)
//upload.setSizeMax(1024 * 1024 * 1024); // 可有可无,中文处理,解决上传数据的中文乱码
//upload.setHeaderEncoding("UTF-8"); // 构造路径存储上传的文件,request.getServletContext().getRealPath("./") 获取的路径 为 WEB-INF 文件夹父级目录,即项目根目录路径,这里路径为 D:\ApacheServer\web_java\HelloWorld\WebContent\\upload\00125943U-0.jpg。这里WebContent为实际项目运行根目录
String uploadPath = request.getServletContext().getRealPath("./") + "upload";
// 如果目录不存在则创建,目录同样只能一级一级创建,不能一次创建多级
File uploadDir = new File( uploadPath );
if (!uploadDir.exists()) {
uploadDir.mkdir();
} // List类传泛型 FileItem 则其创建对象内元素都变为 FileItem 类型
// 将用户请求传给设置好参数的上传对象,返回一个数组
List<FileItem> item_list = upload.parseRequest(request); // 创建 param_map 保存提交表单的键值对
Map param_map = new HashMap();
// 假设有未知个数同表单名的复选框表单提交信息,用 testCheckBox 存该复选框选中的值
Map testCheckBox = new HashMap(); if (item_list != null && item_list.size() > 0) {
// 遍历上传的表单元素
for(FileItem fileItem : item_list){
// fileItem.getFieldName() 表单参数名
String fieldName = fileItem.getFieldName();
// fileItem.getString("UTF-8") 获取表单参数的值,或者上传文件的文本内容
String fieldVal = fileItem.getString("UTF-8"); // 如果页面编码是 UTF-8 的 // 处理在表单中的字段
if (fileItem.isFormField()) {
System.out.println("表单参数名 : " + fieldName + " 参数值为 : " + fieldVal); // 当表单名为 testCheckBox 时,将其不确定个数的多个值存到 Map 对象中
if(fieldName.equals("testCheckBox")) {
testCheckBox.put(testCheckBox.size(), fieldVal); }
// 把post参数以键值对形式重新存到 param_map 列表中。复选框的话最后一个选中的同名值会覆盖之前的值
param_map.put(fieldName, fieldVal);
} // 处理表单中上传文件,这里上传文件的表单名任意都可上传
if (!fileItem.isFormField()) {
// ===============上传文件
// 获取上传的文件名(含扩展名),fileItem.getName()只能获取上传文件的完整名,不能获取其他post表单参数值
String fileName = fileItem.getName();
// 拼接将文件保存本地完整路径及文件+扩展名。File.separator 表示目录分割斜杠
String filePath = uploadPath + File.separator + fileName;
// 将合成的完整路径文件名 filePath 放入 File 对象中,File 对象代表磁盘中实际存在的文件和目录
File saveFile = new File(filePath);
// 限制上传文件扩展名
String suffix_limit[] = {".html", ".jpg", ".jsp"};
SuffixFileFilter filter = new SuffixFileFilter(suffix_limit);
boolean flag = filter.accept(saveFile);
if(!flag) {
System.out.println("上传文件类型不符表单名 : " + fieldName + ",文件名为 : " + fileName);
//return;
}
// 将该上传文件按指定路径保存文件到硬盘
fileItem.write(saveFile);
request.setAttribute("message", "文件上传成功!"); }
}
}
// 可以使用 param_map.get 获取表单参数值了
String name_val = (String) param_map.get("name"); System.out.println("表单name的值 : " + name_val); // 遍历获取复选框的 Map 对象里每个值
for(int i = 0;i<testCheckBox.size();i++) {
System.out.println("复选框i : " + i + "对应值 : " + (String) testCheckBox.get(i));
} } catch (FileUploadException fex) {
fex.printStackTrace();
} catch (Exception ex) {
request.setAttribute("message", "错误信息: " + ex.getMessage());
}
}
}

Servlet 表单及上传文件的更多相关文章

  1. Java模拟表单POST上传文件

    JAVA模拟表单POST上传文件 import java.awt.image.BufferedImage;import java.awt.image.ColorModel;import java.io ...

  2. web 表单方式上传文件方法(不用flash插件)

    原理:使用表单的input type="file"标签,通过ajax提交表单请求,后台获取请求中的文件信息,进行文件保存操作 由于我测试用的做了一个上传文件和上传图片方法,所以我有 ...

  3. ajax异步上传文件和表单同步上传文件 的区别

    1. 用表单上传文件(以照片为例)-同步上传 html部分代码:这里请求地址index.php <!DOCTYPE html> <html lang="en"&g ...

  4. php 利用fsockopen GET/POST 提交表单及上传文件

    1.GET get.php <?php $host = 'demo.fdipzone.com'; $port = 80; $errno = ''; $errstr = ''; $timeout  ...

  5. php 利用 fsockopen GET/POST 提交表单及上传文件

    1.GET get.php <?php$host = 'demo.fdipzone.com';$port = 80;$errno = '';$errstr = '';$timeout = 30; ...

  6. JAVA入门[16]-form表单,上传文件

    一.如何传递参数 使用 @RequestParam 可以传递查询参数.例如:http://localhost:8092/category/detail?id=1 @RequestMapping(&qu ...

  7. CURL模拟表单post提交及相关常用参数的使用(包括提交表单同时上传文件)

    转载自:https://blog.csdn.net/freedomwjx/article/details/43278157 (注:在curl前面加上time如time curl xxx,可以在最后显示 ...

  8. 模拟form表单请求上传文件

    发请求 public string CameraFileUpload(string url,string path,string serverPath,string uploadfileName) { ...

  9. 使用FormData提交表单及上传文件

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head ...

随机推荐

  1. Tkinter 之NoteBook选项卡标签

    一.参数说明 参数 作用 width 选项卡宽度,单位像素 height 选项卡高度 cursor 鼠标停留的样式 padding  外部空间填充,是个最多4个元素的列表 style 设置menubo ...

  2. OSPF外部实验详解

  3. 如何在wcf中用net tcp协议进行通讯

    快速阅读 如何在wcf中用net tcp协议进行通讯,一个打开Wcf的公共类.比较好好,可以记下来. 配置文件中注意配置 Service,binding,behaviors. Service中配置en ...

  4. mui openWindow方法详细说明

    mui.openWindow({ url: 'xxx.html', //String类型,要打开的界面的地址 id: 'id', //String类型,要打开的界面的id styles: { //We ...

  5. vue项目用户登录状态管理,vuex+localStorage实现

    安装vuex cnpm install vuex --save-dev

  6. HearthBuddy中的class276中的地址对应

    2019年09月的 intptr_0 = method_18("mono.dll"); intptr_31 = intptr_0 + 522030; intptr_28 = int ...

  7. 阿里云 商标 SAAS

    商标注册-注册商标查询-商标交易平台-阿里云商标https://tm.aliyun.com/#/ 阿里云商标查询入口-云栖社区-阿里云https://yq.aliyun.com/articles/69 ...

  8. Java 13 特性解读

    Java 13 特性解读    转 https://blog.csdn.net/bjweimengshu/article/details/100978383   2017年8月,JCP执行委员会提出将 ...

  9. 前端速查手册——Note

    目录 自定义弹框(模块框) HTML5新增标签 HTML5新增属性 自定义弹框(模块框) HTML <div style="display:none" id="mo ...

  10. Qt编写自定义控件65-光晕日历

    一.前言 操作系统的更新迭代速度非常快,基本上三五年就有个新版本出来,WIN10操作系统还是一个比较成功的系统,据说现在市场份额越来越大,XP的份额已经很小,WIN7的份额也在逐步减少,在最新的WIN ...