JSP + Servlet 实现的文件上传到服务器的功能

时间:2021-01-27 12:12:07

项目目录结构大致如下:

JSP + Servlet 实现的文件上传到服务器的功能

正如我在上图红线画的三个东西:Dao、service、servlet 这三层是主要的结构,类似 MVC 架构,Dao是模型实体类(逻辑层),service是服务层,servlet是视图层,三者协作共同完成项目。

这里的User是由user表来定义的一个类,再封装增删改查等操作,实现从数据库查询与插入,修改与删除等操作,并实现了分页操作,也实现了将图片放到服务器上运行的效果。

Dao层:主要实现了User类的定义,接口IUserDao的定义与实现(UserDaoImpl);

service层:直接定义一个接口类IUserService,与IUserDao相似,再实现其接口类UserServiceImpl,直接实例化UserDaoImpl再调用其方法来实现自己的方法,重用了代码。详见代码吧;

servlet层:起初是将表User 的每个操作方法都定义成一个servlet 去实现,虽然简单,但是太多了,不好管理,于是利用 基类BaseServlet 实现了“反射机制”,通过获取的 action 参数自己智能地调用对应的方法,而UserServlet则具体实现自己的方法,以供调用,方便许多,详见之前的博文或下述代码。

将文件上传到 tomcat 服务器的编译后运行的过程的某个文件关键要在每次编译后手动为其创建该文件夹来存放相应的上传文件,否则会导致每次重启 tomcat 服务器后该编译后的工程覆盖了原先的,导致上传文件存放的文件夹不存在,导致代码找不到该文件夹而报错,即上传不成功。如下图所示:

JSP + Servlet 实现的文件上传到服务器的功能

主要是考虑图片路径的问题,手工设置路径肯定不能保证不重复,所以取到上传图片的后缀名后利用随机生成的随机数作为图片名,这样就不会重复名字了:

          String extendedName = picturePath.substring(picturePath.lastIndexOf("."),// 截取从最后一个'.'到字符串结束的子串。
				picturePath.length());
	  // 把文件名称重命名为全球唯一的文件名
	  String uniqueName = UUID.randomUUID().toString();
	  saveFileName = uniqueName + extendedName;// 拼接路径名


增加用户时代码如下:

	// 增
	public void add(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		System.out.println("add方法被调用");
		// 获取数据
		int id = 0;
		String username = null;
		String password = null;
		String sex = null;
		Date birthday = null;
		String address = null;
		String saveFileName = null;
		String picturePath = null;
		// 得到表单是否以enctype="multipart/form-data"方式提交
		boolean isMulti = ServletFileUpload.isMultipartContent(request);
		if (isMulti) {
			// 通过FileItemFactory得到文件上传的对象
			FileItemFactory fif = new DiskFileItemFactory();
			ServletFileUpload upload = new ServletFileUpload(fif);

			try {
				List<FileItem> items = upload.parseRequest(request);
				for (FileItem item : items) {
					// 判断是否是普通表单控件,或者是文件上传表单控件
					boolean isForm = item.isFormField();
					if (isForm) {// 是普通表单控件
						String name = item.getFieldName();
						if ("id".equals(name)) {
							id = Integer.parseInt(item.getString("utf-8"));
							System.out.println(id);
						}
						if ("sex".equals(name)) {
							sex = item.getString("utf-8");
							System.out.println(sex);
						}
						if ("username".equals(name)) {
							username = item.getString("utf-8");
							System.out.println(username);
						}
						if ("password".equals(name)) {
							password = item.getString("utf-8");
							System.out.println(password);
						}
						if ("birthday".equals(name)) {
							String birthdayStr = item.getString("utf-8");
							SimpleDateFormat sdf = new SimpleDateFormat(
									"yyyy-MM-dd");
							try {
								birthday = sdf.parse(birthdayStr);
							} catch (ParseException e) {
								e.printStackTrace();
							}
							System.out.println(birthday);
						}
						if ("address".equals(name)) {
							address = item.getString("utf-8");
							System.out.println(address);
						}
						if ("picturePath".equals(name)) {
							picturePath = item.getString("utf-8");
							System.out.println(picturePath);
						}
					} else {// 是文件上传表单控件
							// 得到文件名 xxx.jpg
						String sourceFileName = item.getName();
						// 得到文件名的扩展名:.jpg
						String extendedName = sourceFileName.substring(
								sourceFileName.lastIndexOf("."),
								sourceFileName.length());
						// 把文件名称重命名为全球唯一的文件名
						String uniqueName = UUID.randomUUID().toString();
						saveFileName = uniqueName + extendedName;
						// 得到上传到服务器上的文件路径
						// C:\\apache-tomcat-7.0.47\\webapps\\taobaoServlet4\\upload\\xx.jpg
						String uploadFilePath = request.getSession()
								.getServletContext().getRealPath("upload/");
						File saveFile = new File(uploadFilePath, saveFileName);
						// 把保存的文件写出到服务器硬盘上
						try {
							item.write(saveFile);
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				}
			} catch (NumberFormatException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (FileUploadException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		// 2、封装数据
		User user = new User(id, username, password, sex, birthday, address,
				saveFileName);
		// 3、调用逻辑层API
		IUserService iUserService = new UserServiceImpl();
		// 4、控制跳转
		HttpSession session = request.getSession();
		if (iUserService.save(user) > 0) {
			System.out.println("添加新用户成功!");
			List<User> users = new ArrayList<User>();
			users = iUserService.listAll();
			session.setAttribute("users", users);
			response.sendRedirect("UserServlet?action=getPage");
		} else {
			System.out.println("添加新用户失败!");
			PrintWriter out = response.getWriter();
			out.print("<script type='text/javascript'>");
			out.print("alert('添加新用户失败!请重试!');");
			out.print("</script>");
		}
	}


修改用户时注意考虑图片更改和没更改这两种情况,图片更改时要先获取原图片并删除其在服务器上的图片,再添加新图片到服务器;图片不更改时则无需更新图片路径。

	// 改
	public void update(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		System.out.println("update方法被调用");
		HttpSession session = request.getSession();
		// 获取数据
		int id = (int)session.getAttribute("id");
		String username = null;
		String password = null;
		String sex = null;
		Date birthday = null;
		String address = null;
		String saveFileName = null;
		String picturePath = null;
		IUserService iUserService = new UserServiceImpl();
		// 得到表单是否以enctype="multipart/form-data"方式提交
		boolean isMulti = ServletFileUpload.isMultipartContent(request);
		if (isMulti) {
			// 通过FileItemFactory得到文件上传的对象
			FileItemFactory fif = new DiskFileItemFactory();
			ServletFileUpload upload = new ServletFileUpload(fif);
			try {
				List<FileItem> items = upload.parseRequest(request);
				for (FileItem item : items) {
					// 判断是否是普通表单控件,或者是文件上传表单控件
					boolean isForm = item.isFormField();
					if (isForm) {// 是普通表单控件
						String name = item.getFieldName();
						if ("sex".equals(name)) {
							sex = item.getString("utf-8");
							System.out.println(sex);
						}
						if ("username".equals(name)) {
							username = item.getString("utf-8");
							System.out.println(username);
						}
						if ("password".equals(name)) {
							password = item.getString("utf-8");
							System.out.println(password);
						}
						if ("birthday".equals(name)) {
							String birthdayStr = item.getString("utf-8");
							SimpleDateFormat sdf = new SimpleDateFormat(
									"yyyy-MM-dd");
							try {
								birthday = sdf.parse(birthdayStr);
							} catch (ParseException e) {
								e.printStackTrace();
							}
							System.out.println(birthday);
						}
						if ("address".equals(name)) {
							address = item.getString("utf-8");
							System.out.println(address);
						}
						if ("picturePath".equals(name)) {
							picturePath = item.getString("utf-8");
							System.out.println(picturePath);
						}
					} else {// 是文件上传表单控件
							// 得到文件名 xxx.jpg
						picturePath = item.getName();
						if (picturePath != "") {// 有选择要上传的图片
							// 得到文件名的扩展名:.jpg
							String extendedName = picturePath.substring(
									picturePath.lastIndexOf("."),// 截取从最后一个'.'到字符串结束的子串。
									picturePath.length());
							// 把文件名称重命名为全球唯一的文件名
							String uniqueName = UUID.randomUUID().toString();
							saveFileName = uniqueName + extendedName;// 拼接路径名
							// 得到上传到服务器上的文件路径
							// C:\\apache-tomcat-7.0.47\\webapps\\CommonhelloWorldServlet\\upload\\xx.jpg
							String uploadFilePath = request.getSession()
									.getServletContext().getRealPath("upload/");
							File saveFile = new File(uploadFilePath,
									saveFileName);
							// 把保存的文件写出到服务器硬盘上
							try {
								item.write(saveFile);
							} catch (Exception e) {
								e.printStackTrace();
							}
							// 3、调用逻辑层 API
							// 根据id查询用户并获取其之前的图片
							User user = iUserService.getUserById(id);
							String oldPic = user.getPicturePath();
							String oldPicPath = uploadFilePath + "\\" + oldPic;
							File oldPicTodelete = new File(oldPicPath);
							oldPicTodelete.delete();// 删除旧图片
						}
					}
				}
			} catch (NumberFormatException e) {
				e.printStackTrace();
			} catch (FileUploadException e) {
				e.printStackTrace();
			}
		}
		System.out.println(id + "\t" + username + "\t" + password + "\t" + sex
				+ "\t" + address + "\t" + picturePath + "\t" + birthday);

		// 2、封装数据
		User user = new User(id, username, password, sex, birthday, address,
				saveFileName);

		if (iUserService.update(user) > 0) {
			System.out.println("修改数据成功!");
			List<User> users = new ArrayList<User>();
			users = iUserService.listAll();
			session.setAttribute("users", users);
			// 4、控制跳转
			response.sendRedirect("UserServlet?action=getPage");
		} else {
			System.out.println("修改数据失败!");
			PrintWriter out = response.getWriter();
			out.print("<script type='text/javascript'>");
			out.print("alert('修改数据失败!请重试!');");
			out.print("</script>");
		}
	}


删除的话就比较简单了,直接获取原图片路径并删除,则原图片在服务器上被删除。

不详述了,详见代码吧。代码链接:srcCode