今天做一个简单的商城项目的时候碰到了一个问题,将前台页面传过来的参数直接想当然的使用BeanUtils的populate封装进了bean,去数据库看发现只有自己给bean设置的值,前台传的一个都没有存储进去.查了资料发现,使用了multipart/form-data之后,表单数据都是二进制传输的,request不能识别到,那么只能使用fileitem的isFormFiled方法判断是表单中的数据之后,取出fieldname属性名.还有getString得到属性值.封装进自己创建的map里面.再使用BeanUtils进行封装.贴上代码.
addProduct.jsp
<%@page contentType="text/html; UTF-8" language="java" pageEncoding="UTF-8" %>
<html>
<head>
<title>添加商品</title>
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen"/>
<style type="text/css">
.main {
text-align: center;
border-radius: 20px;
width: 300px;
height: 400px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
td {
white-space: nowrap;
}
</style>
</head>
<body>
<div class="main">
<form action="${pageContext.request.contentType}/addProduct" method="post" enctype="multipart/form-data">
<table>
<tr>
<td>商品名称</td>
<td><input type="text" name="name"/></td>
</tr>
<tr>
<td>商品价格</td>
<td><input type="text" name="price"/></td>
</tr>
<tr>
<td>商品类别</td>
<td>
<select name="category">
<option>请选择</option>
<option value="图书音像">图书音像</option>
<option value="家用电器">家用电器</option>
<option value="服装衣帽">服装衣帽</option>
</select>
</td>
</tr>
<tr>
<td>商品数量</td>
<td><input type="text" name="amount"/></td>
</tr>
<tr>
<td>商品图片</td>
<td><input type="file" name="file"/></td>
</tr>
<tr>
<td>商品描述</td>
<td>
<textarea name="description" cols="20" rows="10"></textarea>
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="提交"/>
<input type="reset" value="重置"/>
<input type="button" value="取消" id="cancel"/>
</td>
</tr>
</table>
</form>
</div>
</body>
<script type="text/javascript">
var cancel = document.getElementById("cancel");
cancel.onclick = function () {
window.location = "${pageContext.request.contentType}/";
}
</script>
</html>
AddProductServlet.java
package com.relic.eStore.web;
import com.relic.eStore.domain.Product;
import com.relic.eStore.exception.ProductException;
import com.relic.eStore.service.ProductService;
import com.relic.eStore.utils.UUIDUtils;
import com.relic.eStore.utils.UploadUtils;
import org.apache.commons.beanutils.BeanUtils;
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.IOUtils;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class AddProductServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建一个map存储属性名和属性值
Map<String, String[]> info = new HashMap<>();
//处理前台的图片上传操作
DiskFileItemFactory factory = new DiskFileItemFactory();
//设置缓存路径
factory.setRepository(new File(req.getServletContext().getRealPath("/upload/tmp")));
ServletFileUpload upload = new ServletFileUpload(factory);
//解决文件名包含中文乱码问题
upload.setHeaderEncoding("UTF-8");
try {
List<FileItem> fileItems = upload.parseRequest(req);
Product product = new Product();
info.put("id", new String[]{UUIDUtils.getUUID()});
//根据item是否是上传组件,进行上传操作
for (FileItem fileItem : fileItems) {
if (fileItem.isFormField()) {
info.put(fileItem.getFieldName(), new String[]{fileItem.getString("UTF-8")});
} else {
//获取文件名称
String filename = UploadUtils.getFilename(fileItem.getName());
//获取随机的文件名
String uuidName = UploadUtils.getUuidName(filename);
//根据文件名得到2级目录
String _directory = UploadUtils.getRandomDir(uuidName);
//得到真实路径
File directory = new File(req.getServletContext().getRealPath("/upload" + _directory));
if (!directory.exists()) {
directory.mkdirs();
}
File file = new File(directory, uuidName);
//完成上传操作
IOUtils.copy(fileItem.getInputStream(), new FileOutputStream(file));
//删除临时文件
fileItem.delete();
//将路径封装
info.put("imgUrl", new String[]{file.getAbsolutePath()});
}
}
//将info中存储的信息封装进bean
BeanUtils.populate(product, info);
//调用service方法,存储product信息
ProductService service = new ProductService();
service.addProduct(product);
resp.sendRedirect(req.getContextPath() + "/index.jsp");
return;
} catch (IllegalAccessException | FileUploadException | InvocationTargetException | ProductException e) {
e.printStackTrace();
}
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
UploadUtils.java
package com.relic.eStore.utils;
public class UploadUtils {
//根据fileItem得到的文件名得到只包含名称和文件格式的文件名
public static String getFilename(String name) {
int index = name.indexOf("//");
if (index == -1) {
return name;
}
return name.substring(index + 1);
}
//根据文件名的hashcode生成2级目录
public static String getRandomDir(String filename) {
int hashcode = filename.hashCode();
//1级目录
int d1 = hashcode & 0xf;
//2级目录
int d2 = (hashcode >> 4) & 0xf;
return "/" + d1 + "/" + d2;
}
//返回随机的uuid+文件格式的文件名
public static String getUuidName(String filename) {
String uuid = UUIDUtils.getUUID();
int index = filename.indexOf(".");
if (index == -1) {
return uuid;
}
return uuid + filename.substring(index);
}
}
service和dao就不贴了,实现功能就是向数据库添加一个product实体