JavaWeb 文件上传下载和图片验证码

超详细的Java知识点路线图


文件上传

这里使用的是Apache的common-fileupload包

准备工作:

  1. 下载导入jar包
    common-fileupload 文件上传
    common-io 文件IO
  2. 在JSP的fom标签中,添加属性:enctype=“multipart/form-data”,请求方法必须是post
  3. 表单中使用file控件上传

相关API:
ServletFileUpload类
主要方法:

  • isMultipartContent(Request对象) 判断表单中是否有上传内容,静态
  • FileItemIterator getItemIterator(Request对象) 获得表单项目的迭代器
  • setFileSizeMax(int 长度) 设置每个文件最大的大小
  • setSizeMax(int 长度) 设置上传的总大小

FileItemIterator类 表单项目的迭代器

  • hasNext 判断还有没有项目没有读取
  • FileItemStream next 读取下一个项目

FileItemStream类 上传项目

  • getFieldName 获得表单字段的名称
  • getName 获得文件名
  • openStream 打开输入流
  • isFormField 判断是否是一般的表单项

Streams类 文件流工具类

  • asString(输入流,“编码类型”) 从流中读取字符串
  • copy(输入流 , 输出流 , 结束是否关闭流) 复制输入流的数据到输出流
/**
 * 上传文件的Servlet
 * @author xray
 *
 */
public class UploadServlet extends HttpServlet{
	
	public static final String UPLOAD_DIR = "/Users/xray/Documents/xray_mac/upload";
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		MyLogger log = new MyLogger(UploadServlet.class);
		log.info("start upload...");
		//判断请求中是否存在上传内容
		if(ServletFileUpload.isMultipartContent(req)){
			//创建上传对象
			ServletFileUpload upload = new ServletFileUpload();
			//设置上传每个文件的最大长度
			upload.setFileSizeMax(1024 * 1024);
			//设置上传文件的总大小
			upload.setSizeMax(1024 * 1024 * 2);
			try {
				//获得文件项目的迭代器
				FileItemIterator iterator = upload.getItemIterator(req);
				//对迭代器进行迭代
				while(iterator.hasNext()){
					//获得每个表单项
					FileItemStream item = iterator.next();
					//获得表单项的输入流
					InputStream is = item.openStream();
					//判断该项是普通表单项目还是上传项目
					if(item.isFormField()){
						//如果是一般项目,读取文字内容
						String value = Streams.asString(is,"UTF-8");
						//判断项目的字段名
						switch(item.getFieldName()){
						case "username":
							log.info("用户名:"+value);
							break;
						case "password":
							log.info("密码:"+value);
							break;
						}
					}else{
						//如果是上传项目,就把文件保存到服务器的目录中 C:/xxx/aa/123.jpg
						String filename = UPLOAD_DIR + "/" + 
								System.currentTimeMillis()+"-"+
								FilenameUtils.getName(item.getName());
						OutputStream out = new FileOutputStream(filename);
						Streams.copy(is, out, true);

						log.info(filename+"图片保存完毕");
					}
				}
			} catch (FileUploadException e) {
				e.printStackTrace();
			}
		}
		log.info("end upload...");
	}
}

文件下载

下载Servlet

/**
 * 下载文件的Servlet
 * @author xray
 *
 */
public class DownloadServlet extends HttpServlet{

	public static final String DOWNLOAD_DIR = "/Users/xray/Documents/xray_mac/download";
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		MyLogger log = new MyLogger(DownloadServlet.class);
		//获得文件名
		String filename = req.getParameter("filename");
		log.info("文件名:"+filename);
		//处理中文乱码
		filename = new String(filename.getBytes("ISO-8859-1"),"UTF-8");
		//获得服务器上磁盘文件的输入流
		InputStream in = new FileInputStream(DOWNLOAD_DIR+"/"+filename);
		//获得发送浏览器的输出流
		OutputStream out = resp.getOutputStream();
		//设置响应头
		resp.setHeader("content-disposition", "attachment;filename="+
						URLEncoder.encode(filename, "UTF-8"));
		//读写文件流
		Streams.copy(in, out, true);
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doGet(req,resp);
	}
}

下载页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<a href="download.do?filename=Oracle超详细教程.pdf">Oracle超详细教程.pdf</a><br>
	<a href="download.do?filename=Oracle经典教程.pdf">Oracle经典教程.pdf</a>
</body>
</html>

图片验证码

作用:提高安全性,提升黑客破解难度。
实现思路:
1、在Servlet中创建图片
2、随机生成4个字母或数字
3、随机绘制线条
4、将图片发送给浏览器
需要类:
BufferedImage 带缓冲的图片
Graphics 绘图对象
ImageIO 实现图片的IO流读写

/**
 * 生成验证码的Servlet
 *
 */
@WebServlet("/code.do")
public class ValidateCodeServlet extends HttpServlet{
	
	public static final String CODES = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
	public static final int WIDTH = 80;
	public static final int HEIGHT = 35;
	public static final int NUMBER = 4;
	public static final int FONT_SIZE = 20;
	public static final Color[] COLORS = {Color.BLACK,Color.BLUE,Color.CYAN,Color.DARK_GRAY,Color.GREEN,Color.LIGHT_GRAY,
			Color.MAGENTA,Color.ORANGE,Color.PINK,Color.RED,Color.WHITE,Color.YELLOW};
	
	protected void doGet(javax.servlet.http.HttpServletRequest req, javax.servlet.http.HttpServletResponse resp) throws javax.servlet.ServletException ,java.io.IOException {
		doPost(req,resp);
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//创建缓冲图片对象
		BufferedImage image = new BufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_INT_ARGB);
		//创建绘图对象
		Graphics g = image.getGraphics();
		//设置字体大小
		g.setFont(new Font("宋体",Font.PLAIN,FONT_SIZE));
		//设置颜色
		g.setColor(Color.GRAY);
		//填充矩形方块
		g.fillRect(0, 0, WIDTH, HEIGHT);
		//随机产生几个字母或数字
		Random random = new Random();
		char[] codes = new char[NUMBER];
		for(int i = 0;i < NUMBER;i++){
			g.setColor(COLORS[random.nextInt(COLORS.length)]);
			//在字符串中随机取一个字符
			codes[i] = CODES.charAt(random.nextInt(CODES.length()));
			//绘制该字符
			g.drawString(codes[i] + "", i * FONT_SIZE + 5, FONT_SIZE);
			//绘制随机的线条
			g.setColor(COLORS[random.nextInt(COLORS.length)]);
			g.drawLine(random.nextInt(WIDTH), random.nextInt(HEIGHT),random.nextInt(WIDTH), random.nextInt(HEIGHT));
		}
		//将验证码保存到Session中
		req.getSession().setAttribute("code", new String(codes));
		//取消浏览器对图片的缓存
		resp.addHeader("Cache-Control", "no-cache");
		//发送图片给浏览器
		ImageIO.write(image, "PNG", resp.getOutputStream());
	}

}

登录JSP

<div id="login">
	<p id="title">后台管理系统</p>
	<span id="error_msg">${error_msg}</span>
	<form action="login.do" method="post">
		<input name="user_tel" type="text" placeholder="请输入手机号"><br>
		<input name="user_password" type="password" placeholder="请输入密码"><br>
		<input name="code" type="text" placeholder="请输入验证码"><br>
		<img src="code.do" id="code" onclick="changeCode()"><br>
		<input type="submit" value="登录">
	</form>
</div>
<script type="text/javascript">
	function changeCode(){
		document.getElementById("code").src = "code.do?x="+Math.random();
	}
</script>

登录Servlet中添加验证码的逻辑:

//获得用户填写的验证码
String code = req.getParameter("code");
//获得Session中的验证码
String code2 = (String) req.getSession().getAttribute("code");
//判断验证码是否正确
if(code2==null || !code2.equals(code)){
	req.setAttribute("error_msg", "验证码不正确");
	req.getRequestDispatcher("login.jsp").forward(req, resp);
	return;
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

恒哥~Bingo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值