1、普通表单上传enctype="application/x-www-form-urlencoded",后台getParamter()获得。
2、上传图片,文件采用的格式:enctype="multipart/form-data" 。注意:上传表单采用post方式提交,不能使用get方式提交
普通表单与非普通表单提交区别:非表单提交是采用二进制的形式传递到后台的,当然就不能使用常规方式获得数据。
/**
* 普通form上传,图片、文件上传FileItem不一样
* 除了共同的content-disposition:form-data name="XXX"
* 文件、图片上传还带有文件名字/图片名字(123.jpg)和contentType参数
* @author Liaq
*/
public class uploadServlet extends HttpServlet{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
//文件项工厂,将上传文件放在磁盘中
FileItemFactory factory = new DiskFileItemFactory();
/*上传文件大于设置的大小,放在临时文件中,如果再将图片写在服务器上,
临时文件中的图片消失。如果不写在服务器上,临时文件中还存在图片。
DiskFileItemFactory factory2 = new DiskFileItemFactory();
factory2.setSizeThreshold(1024*1024*2);
factory2.setRepository(new File("d:/upload"));
*/
//处理上传的类
ServletFileUpload upload = new ServletFileUpload(factory);
try {
//得到所有的FileItem
List<FileItem> list = upload.parseRequest(request);
//遍历
Iterator<FileItem> iterator = list.iterator();
while(iterator.hasNext()){
FileItem item = iterator.next();
if (item.isFormField()) {//判断当前输入框是否为formField,formFile相当与用户名输入框。文件,图片上传就不是formField格式
//普通表单元素
System.out.println(item.getContentType());//null
System.out.println(item.getFieldName());//username
System.out.println(item.getName());//null
System.out.println(item.getSize());//上传大小
System.out.println(item.getString());//输入框中内容
System.out.println(item.getInputStream());//读取流
System.out.println(item.getOutputStream());//写入流
}else{
//上传表单
System.out.println(item.getContentType());//例如application/postscript
System.out.println(item.getFieldName());//file标签的那么值
System.out.println(item.getName());//123.jpg
System.out.println(item.getSize());//文件大小
System.out.println(item.getString());//二进制流
System.out.println(item.getInputStream());//读取流
System.out.println(item.getOutputStream());//写入流
item.write(new File(getServletContext().getRealPath("/upload"),item.getName()));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
简单的优化:
public class UploadDemo extends HttpServlet{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HashMap<String, String> formField = new HashMap<String, String>();
/**
* CFile设计:
* 两个变量:name文件名字、path文件路径
*/
HashMap<String, CFile> notFormField = new HashMap<String, CFile>();//string 表示上传标签的name值
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
try {
List<FileItem> fileItems = upload.parseRequest(request);
if (fileItems.size()>0) {
for (FileItem fileItem : fileItems) {
if (fileItem.isFormField()) {
formField.put(fileItem.getFieldName(), fileItem.getString());
}else{
String randomName = new Random().nextInt(188888)+fileItem.getName().substring(fileItem.getName().lastIndexOf("."));
/*
CFile cFile = new CFile(fileItem.getName(), getServletContext().getRealPath("/upload/")+ randomName);
notFormField.put(fileItem.getFieldName(), cFile);
*/
fileItem.write(new File(getServletContext().getRealPath("/upload"), randomName));
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
servlet上传工具类:
/**
* 1、上传后缀名要符合,所以定义数组判断
* 2、将普通表单的值放在map中,使用装饰模式取普通表单的值。所以定义为map
* 3、图片、文件上传放在item中,供savefile方法使用,所以定义为list
* 4、判断当前是否为非普通表单提交,所以定义变量boolean flag
* 5、上传的文件名字不能重复,所以要使用uuid getCurrentTime random函数,生成文件名字
* 6、上传文件有大小限制。factory.setSizeThreshold(1024*1024*2)
* 7、超过上传大小限制。放的文件目录:factory.setRepository(new File("d:/upload"))
* 注意:上传文件大于设置的大小,放在临时文件中,如果再将图片写在服务器上,临时文件中的图片消失。如果不写在服务器上,临时文件中还存在图片。
* @author Liaq
*
*/
public class ServletRequestWithUpload extends HttpServletRequestWrapper {
//文件格式数组
private String[] exts = {"jpg","doc","rar","zip","txt","bmp"};
//普通表单
HashMap<String, String[]> maps = new HashMap<String, String[]>();
//上传表单
List<FileItem> items = new ArrayList<FileItem>();
//是否为上传表单
private boolean flag;
public ServletRequestWithUpload(HttpServletRequest request) {
super(request);
//初始化上传的参数
flag = ServletFileUpload.isMultipartContent(request);
if (flag) {
DiskFileItemFactory factory = new DiskFileItemFactory(1024*1024*2, new File("d:/upload"));
ServletFileUpload fileUpload = new ServletFileUpload(factory);
try {
List<FileItem> fileItems = fileUpload.parseRequest(request);
for (FileItem fileItem : fileItems) {
if (fileItem.isFormField()) {
maps.put(fileItem.getFieldName(), new String[]{new String(fileItem.getString().getBytes("iso8859-1"),"UTF-8")});
}else{
items.add(fileItem);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public String getParameter(String name) {
if (flag) {//普通表单的值
return maps.get(name) == null || maps.get(name).length == 0?"":maps.get(name)[0];
}else{
return super.getParameter(name);
}
}
public void saveFile(String path){//上传文件、图片的处理函数
String realPath = getSession().getServletContext().getRealPath("/");
String pathName =realPath + path;
boolean v = false;
for (FileItem item : items) {
String fileName = item.getName();
for (String ext : exts) {
if (fileName.endsWith(ext)) {
v = true;
break;
}
}
if (v) {
String randomFileName = UUID.randomUUID().toString()+System.currentTimeMillis()
+new Random().nextInt(1999999)+fileName.substring(fileName.lastIndexOf("."));
try {
item.write(new File(pathName,randomFileName));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}