文件上传中form表单的enctype="multipart/form-data" 为二进制文件传输
在struts2中 表单取值比较简单 因为框架已经帮我们做好的表单域的取值
但是在非框架中 取值就相对麻烦了 不能通过request.getParameter(name) 去取值
不过我们可以使用相关的jar去实现文件的上传和下载 比如 DiskFileUpload
前段时间 在做文件上传的时候 需要传递一个复选框的值 以及 相同名字的几个textarea的值
在非上传中 我们可以通过request.getParameterValues(name)方法 把需要的值变为一个字符串数组
但是DiskFileUpload中没有相关的方法 通过参考项目中以前的方法 再加以修改 实现了相关功能
boolean success = false;
Map pMap = new LinkedHashMap();//form Field map
request.setCharacterEncoding("GBK");
try {
//通过FileUpload组建封装表单值到map对象中
DiskFileUpload fu = new DiskFileUpload();
fu.setSizeMax(30 * 1024 * 1024);// 设置最大文件尺寸,这里是14MB
fu.setSizeThreshold(1024 * 64);// 设置缓冲区大小,这里是64kb
List fileItems = fu.parseRequest(request);// 得到所有的field
Iterator itor = fileItems.iterator();
// 依次处理每一个field
while (itor.hasNext()) {
FileItem fi = (FileItem) itor.next();
if (fi.isFormField()){//表单处理
if(pMap.get(fi.getFieldName())!=null){
pMap.put(fi.getFieldName(),pMap.get(fi.getFieldName())+"$"+org.apache.commons.lang.StringEscapeUtils.escapeSql(fi.getString("GBK")));
}else{
pMap.put(fi.getFieldName(),org.apache.commons.lang.StringEscapeUtils.escapeSql(fi.getString("GBK")));
}
} else {//附件处理
if (fi.getName() != null) {
if (fi.getName().indexOf(".") != -1) {//有扩展名的指定类型文件
pMap.put(fi.getFieldName(), fi);
}
}
}
}
通过DiskFileUpload中的fu.parseRequest(request)方法 把request中的表单属性 转化为List对象
然后遍历fileItems 把对应表单的值放在map对象中 判断map是否存在某个key 存在就拼接value
if(pMap.get(fi.getFieldName())!=null){
pMap.put(fi.getFieldName(),pMap.get(fi.getFieldName())+"$"+org.apache.commons.lang.StringEscapeUtils.escapeSql(fi.getString("GBK")));
}else{
pMap.put(fi.getFieldName(),org.apache.commons.lang.StringEscapeUtils.escapeSql(fi.getString("GBK")));
}
这样我们就实现了表单中相同name的标签的取值问题
接下来就是取值 封装在实体类中
int exam_year = Integer.parseInt(pMap.get("exam_year").toString());
String name = pMap.get("exam_year").toString();
按照正常的思路我们需要这样进行取值 假如表单的属性就几个还好 假如很多呢?
而且表单中有的属性可以为空 在取值封装到实体类中时候 如果map的取值为空 就会报错
因此还要对map对象进行判断
if(pMap.get("q_paper_type")!=null){
q_paper_type =Integer.parseInt(pMap.get("q_paper_type").toString());
}
非常的麻烦
参考以前的项目 发现apache commons 的一个jar commons-beanutils-1.7.0.jar
使用BeanUtils轻松实现实体类对象的封装
引用<%@ page import="org.apache.commons.beanutils.BeanUtils" %>
question 是我们的实体类对象
BeanUtils.populate(question, pMap);
就是这么简单 而且会初始化对应的字段 map中某些属性为空时 也不会报错
附上文件的操作:
//附件上传
if(pMap.get("file")!=null){
FileItem fi = (FileItem) pMap.get("file");
String attachExtName = org.apache.commons.lang.StringUtils.lowerCase(fi.getName().substring(fi.getName().lastIndexOf(".")));
if (!".zip".equals(attachExtName)) {
out.print("<script>alert('文件类型错误,请上传zip格式文件!');history.go(-1);</script>");
return; //解压缩,格式错误,非zip文件
}
if(fi.getSize()>3*1024*1024){
out.print("<script>alert('zip文件不能超过3M!');window.close();</script>");
return; //解压缩,格式错误,非zip文件
}
question.setBodyPackage(fi.getInputStream());
}
-------------------------------------------------------
下面是一个公用方法 任何实体类都可以复制这段代码
public static void paramPrepare(Object q, HttpServletRequest request) throws Exception {
// request 变量和附件处理,生成q对象
Map pMap = new HashMap();// form Field map
Enumeration enu = request.getParameterNames();
while (enu.hasMoreElements()) {
Object key = enu.nextElement();
pMap.put(key, ParamUtils.getParameter(request, (String) key));
}
BeanUtils.copyProperties(q, pMap);
}
User u = new User();
User.paramPrepare(user,request);
把request的信息封装到实体对象里面