// 文件路径 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. spark的一些基本概念和模型

    Application application和Hadoop MapReduce类似,都是指用户编写的spark应用程序,其中包含了一个driver功能的代码和分布在集群中多个节点运行的executo ...

  2. C# WinForm中的一些小问题

    前言 记一些C#窗体应用编程中的小问题. DataGridView 设置Selected = true后实际选中行标依旧是第一行. 通常通过this.dataGridView1.Rows[i].Sel ...

  3. [设计原则与模式] 如何理解TDD的三条规则

    cp from  :  https://blog.csdn.net/ibelieve1974/article/details/54948031 如何理解Bob大叔的TDD三条规则?第一条和第三条讲的是 ...

  4. 创建加载bean的实例

    一.创建实例 工程的结构如下图 1.创建接口 public interface Person { public void setName(String name); public String say ...

  5. 使用idea创建第一个springboot项目

    版权声明:版权归作者所有,转载请注明出处. https://blog.csdn.net/qq_34205356/article/details/81098354 前言:如今springboot越来越火 ...

  6. log4j实现日志自动清理功能

    log4j不支持自动清理功能,但是log4j2版本支持,log4j2是log4j的升级版,比logback先进. log4j升级为log4j2(不需要改动代码)https://blog.csdn.ne ...

  7. 快速克隆网站利器-teleport ultra

    快速克隆网站利器-teleport ultra 一.下载 二.操作步骤 第一步:打开这个软件 第二步点击file.下拉选择 New Project Wizred,弹出如下下拉框 这里我们使用第一个或者 ...

  8. 生成model笔记

    https://github.com/yscacaca/DeepSense/tree/master/android_test这个才是真正的部署代码,跑这个代码就好. 跑python sample_mo ...

  9. linux系统telnet端口不通能收到SYN但不回SYN+ACK响应问题排查(转载)

    linux系统telnet端口不通能收到SYN但不回SYN+ACK响应问题排查 一:背景:一台机器从公司办公网登录不上且所有tcp端口都telnet不通,但是通过同机房同的其它机器却可以正常访问到出问 ...

  10. Python 线程,with的作用(自动获取和释放锁Lock)

    Python 线程,with的作用(自动获取和释放锁Lock) import threading import time num= #全局变量多个线程可以读写,传递数据 mutex=threading ...