文件上传,文件下载与生成验证码

1、文件上传

1. upload概念

uoload : 文件上传
客户端通过表单的文件域file, 把客户端的文件上传到服务器的硬盘上

2. 页面要求

(1)必须要有文件域 : <input type="file">
(2)表单提交的方式为 : method = "post"
(3)表单的enctype为 : multipart/form-data
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

<form action="/LianXi/FileUpLoadServlet" method="post" enctype="multipart/form-data">
	<label>用户姓名 : </label>
	<input type="text" name="uname"><br>
	<label>用户密码 : </label>
	<input type="password" name="upwd"><br>
	<label>用户头像 : </label>
	<input type="file" name="uphoto"><br>
	<input type="submit" value="提交">
</form>


</body>
</html>

3. servlet

package com.java.filter;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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 com.java.entity.User;

public class UploadServlet extends HttpServlet {
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//方式一 : 失败
		//表单当中设置了enctype="multipart/form-data", 那么设置编码集和获取参数的方法失效
		//resp.getWriter().print(req.getParameter("uname") + "," + req.getParameter("upwd") + "," + req.getParameter("uphoto"));
		
		//方式二 : 当多部件表单提交时, 只能使用request的字节输入来接受数据
		/*
		 * InputStream in = req.getInputStream(); byte[] buff = new byte[1024*1024]; int
		 * n = in.read(buff); String message = new String(buff,0,n,"utf-8");
		 * resp.getWriter().print(message);
		 */
		
		
		//方式三 : 
		DiskFileItemFactory factory = new DiskFileItemFactory();//创建工厂对象
		ServletFileUpload upload = new ServletFileUpload(factory);//创建一个多部件表单解析器对象, 并关联工厂对象
		User user = new User();
		FileOutputStream fos = null;
		try {
			List<FileItem> list = upload.parseRequest(req);
			for (FileItem fileItem : list) {
                //获取文件域对象的文件类型, 普通组件为null
//				System.out.println("getContentType-->" + fileItem.getContentType());
//				System.out.println("getFieldName-->" + fileItem.getFieldName());//获取组件的name值
//				System.out.println("getName-->" + fileItem.getName());//获取文件域的文件名
//				System.out.println("getSize-->" + fileItem.getSize());//获取数据的字节格式
//				System.out.println("getString-->" + fileItem.getString());//获取数据的字符串
//				System.out.println("isFormField-->" + fileItem.isFormField());//判断是否为普通组件
//				System.out.println("getInputStream-->" + fileItem.getInputStream());//获取数据的字节输入流
//				System.out.println("========================================================");
				
				if(fileItem.isFormField()) {//是普通组件
					String fieldName = fileItem.getFieldName();
					String fieldValue = fileItem.getString();
					//解决文字乱码方法一 : 先对乱码进行iso-8859-1编码, 再用正确的编码解码
					//fieldValue = new String(fieldValue.getBytes("iso-8859-1"), "utf-8");
					//方法二 : 取值时就调用可设置编码集的方法
					fieldValue = fileItem.getString("utf-8");
					
					//判断是哪个值
					if("uname".equals(fieldName)) {
						user.setUname(fieldValue);
					}else if("upwd".equals(fieldName)){
						user.setUpwd(fieldValue);
					}
				}else {//是文件域
					//组件名称和文件输入流
					String fieldName = fileItem.getFieldName();
					String fileName = fileItem.getName();
					InputStream in = fileItem.getInputStream();
					//把文件保存在硬盘中
					//File descFile = new File("C:\\Users\\DreamBack\\Desktop\\Java\\imgs\\" + UUID.randomUUID() + fileName);
					//fos = new FileOutputStream(descFile);
//					
					//把文件存入服务器
					String path = req.getServletContext().getRealPath("/imgs/" + UUID.randomUUID() + fileName);
					File descFile = new File(path);
					fos = new FileOutputStream(descFile);
					byte[] buff = new byte[1024];
//					int n;
//					while((n=in.read(buff))!=-1) {
//						fos.write(buff, 0, n);
//					}
					//调用方法进行传输
					IOUtils.copy(in, fos);
					System.out.println(descFile.getName());
					user.setUphoto(descFile.getName());//设置文件路径给user
					//C:\Users\DreamBack\Desktop\Java\JavaEclipse\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps\Day1014Upload\imgs
				}
				
				
			}
			
			
		} catch (FileUploadException e) {
			throw new RuntimeException(e);
		}finally {
			if(fos != null) {
				fos.close();
			}
		}
		
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

2、文件下载

1 download概念

download:文件下载:
      客户端点击页面的超链接  把服务器端的文件下载并保存到客户端的硬盘上

2 jsp

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!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>文件下载</title>
</head>
<body>
	 <h1>文件下载</h1>
     <a  href="<c:url value='/FileDownLoadServlet?fileName=1.jpg'/>">图片1</a><br/>
     <a  href="<c:url value='/FileDownLoadServlet?fileName=2.jpg'/>">图片2</a><br/>
     <a  href="<c:url value='/FileDownLoadServlet?fileName=3.jpg'/>">图片3</a><br/>
     <a  href="<c:url value='/FileDownLoadServlet?fileName=4.jpg'/>">图片4</a><br/>
     <a  href="<c:url value='/FileDownLoadServlet?fileName=5.jpg'/>">图片5</a><br/>
     <a  href="<c:url value='/FileDownLoadServlet?fileName=6.jpg'/>">图片6</a><br/>
</body>
</html>

3 servlet

package servlet;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FileDownLoadServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 设置编码集UTF-8
		request.setCharacterEncoding("UTF-8");
		// 获取文件名字
		String fileName = request.getParameter("fileName");
		// 获取imgs的路径:
		String path = request.getServletContext().getRealPath("/imgs");
		// 绑定原文件路径和名称
		File yuanFile = new File(path, fileName);
		// 创建输入流 读取源文件的信息
		FileInputStream fin = new FileInputStream(yuanFile);
		// 根据文件名字 获取文件的大类型
		String type = request.getServletContext().getMimeType(fileName);
		// 设置两个响应头
		// 响应头ContentType指定响应内容的类型
		response.setHeader("Content-Type", type);
		// 响应头Content-Disposition形式 指定以附件形式保存响应的信息
		response.setHeader("Content-Disposition", "attachment;filename=" + (URLEncoder.encode(fileName, "utf-8")));
		// 一边通过输入流读取信息 一边通过response的输出流写出去
		OutputStream out = response.getOutputStream();
		byte[] arr = new byte[1024];
		int n;
		while ((n = fin.read(arr)) != -1) {
			out.write(arr, 0, n);
		}
		fin.close();
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

3、验证码

1.java实现画验证码

package util;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.imageio.ImageIO;

public class YanZhengMa {

	public static void main(String[] args) {
		System.out.println(getYanZhengMa());
	}

	public static String getYanZhengMa() {
		String path;
		String message = "3456789abcdefghjkmnpqstuvwxy";
		// 1.在内存中开辟空间 用于画画
		BufferedImage bi = new BufferedImage(200, 50, BufferedImage.TYPE_INT_BGR);
		// 2.获取画笔
		Graphics2D g = (Graphics2D) bi.getGraphics();
		// 3.涂染料 画背景
		g.setColor(Color.WHITE);
		// 4.画背景:长方形
		g.fillRect(2, 2, 195, 45);
		// 5.画主题 随机四五个字符
		String yzm = "";
		for (int i = 0; i < 4; i++) {
			yzm += message.charAt((int) (Math.random() * (message.length())));
		}
		// 6.给字符设置文字样式
		Font font = new Font(null, Font.BOLD, 34);
		g.setFont(font);
		// 7.把字符串中的所有字符画到画布上
		for (int i = 0; i < yzm.length(); i++) {
			// 8.笔蘸墨
			g.setColor(new Color((int) (Math.random() * 100 + 120), (int) (Math.random() * 100 + 120),
					(int) (Math.random() * 100 + 120)));
			// 9.写字
			g.drawString(yzm.charAt(i) + "", i * 45 + 10, 40);
		}
		// 10.画干扰线
		for (int i = 0; i < (int) (Math.random() * 5 + 5); i++) {
			g.setColor(new Color((int) (Math.random() * 50 + 120), (int) (Math.random() * 50 + 120),
					(int) (Math.random() * 50 + 120)));
			g.drawLine(2, (int) (Math.random() * 43 + 2), 195, (int) (Math.random() * 43 + 2));
		}
		try {
			// 11.创建流与目的文件关联
			path = "F:\\" + (int) (Math.random() * 100 + 120) + ".jpg";
			File muDiFile = new File(path);
			FileOutputStream fout = new FileOutputStream(muDiFile);
			// 12.把内存中BufferedImage中的信息通过输出流写道目的文件中
			ImageIO.write(bi, "JPEG", fout);
			fout.close();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		return path;
	}

}

2. web实现验证码

  • 页面的img的src请求servlet 生成验证码图片
  • servlet需要把验证码保存到session中 用于登录判断输入的验证码是否正确
  • 登录的servlet中通过判断请求参数的验证码和session中·的验证码是否一致 一致才登录成功

jsp:login.jsp

<%@page import="util.YanZhengMa"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用户登录</title>
</head>
<body>
<h1>用户登录表单</h1>
<c:if test="${not empty requestScope.message}">
    <h3>${requestScope.message}</h3>
</c:if>
<form method="get" action="<c:url value='/YZ_servlet' />">
    <table>
        <tr>
            <th>用户名称:</th>
            <td><input type="text" name="uname"/></td>
        </tr>
        <tr>
            <th>用户密码:</th>
            <td><input type="password" name="upwd"/></td>
        </tr>
        <tr>
            <th><img src="<c:url value='/YZM_servlet'/>" id="img_yzm"/></th>
            <td><input type="text" name="uyzm"/></td>
        </tr>
        <tr>
            <th colspan="2"><INPUT type="reset" value="重置"/>&nbsp;&nbsp;&nbsp;&nbsp;
                <INPUT type="submit" value="登录"/></th>
        </tr>
    </table>
</form>

<!-- 添加js事件  点击图片 图片更新 -->
<script type="text/javascript">
    //文档加载完毕 给img_yzm注册点击事件
    window.onload=function(){
        //获取img_yzm
        var oimg=document.getElementById("img_yzm");
        oimg.onclick=function(){
            //请求时 为了不使用缓存  添加一个无用的参数  参数值每次不同即可
            this.src="<c:url value='/YZM_servlet?n='/>"+Math.random();
        }
    }
</script>
	
</body>
</html>

servlet:生成验证码

package servlet;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class YZM_servlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String message = "3456789abcdefghjkmnpqstuvwxy";
		// 1 在内存中开辟空间 用于画画
		BufferedImage bin = new BufferedImage(148, 33, BufferedImage.TYPE_INT_RGB);
		// 2 获取画笔
		Graphics2D g = (Graphics2D) bin.getGraphics();
		// 3 涂染料 画背景
		g.setColor(Color.WHITE);
		// 4 画背景:长方形
		g.fillRect(2, 2, 150, 35);
		// 5 画主题 随机四五个字符
		String str = "";
		for (int i = 0; i < 4; i++) {
			str += message.charAt((int) (Math.random() * message.length()));
		}
		// 6 给字符设置文字样式
		Font font = new Font(null, Font.BOLD, 20);
		g.setFont(font);
		// 7 把字符串中的所有字符画到画布上
		for (int i = 0; i < str.length(); i++) {
			// 8 笔蘸墨
			g.setColor(new Color((int) (Math.random() * 100 + 120), (int) (Math.random() * 100 + 120),
					(int) (Math.random() * 100 + 120)));
			// 9 写字
			g.drawString(str.charAt(i) + "", i * 40 + 5, 22);
		}
		// 10 画干扰线
		for (int i = 0; i < (int) (Math.random() * 5 + 5); i++) {
			g.setColor(new Color((int) (Math.random() * 50 + 120), (int) (Math.random() * 50 + 120),
					(int) (Math.random() * 50 + 120)));
			g.drawLine(2, (int) (Math.random() * 43 + 2), 195, (int) (Math.random() * 43 + 2));
		}
		// 11 把验证码的信息装入session
		request.getSession().setAttribute("yzm", str);
		// 12 把内存中图片的信息通过respionse的输出流 响应给客户端
		ImageIO.write(bin, "JPEG", response.getOutputStream());
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

servlet:判断验证码登录

package servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import util.YanZhengMa;

public class YZ_servlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		// 获取请求参数
		String uname = request.getParameter("uname");
		String upwd = request.getParameter("upwd");
		String uyzm = request.getParameter("uyzm");
		String message = "";
		// 判断参数的正确
		if (!uname.equals("张三")) {
			message = "用户名错误!";
		} else if (!upwd.equals("123")) {
			message = "用户密码错误!";
		} else {
			String yzm = request.getSession().getAttribute("yzm") + "";
			if (!uyzm.equals(yzm)) {
				message = "验证码错误!";
			}
		}
		// 如果message有值 登录失败 回到登录页面
		if (!message.isEmpty()) {
			request.setAttribute("message", message);
			request.getRequestDispatcher("/login.jsp").forward(request, response);
			return;
		}
		response.getWriter().print("<font color='red'>" + uname + "登录成功!</font>");

	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
posted @ 2021-10-16 16:47  RenVei  阅读(263)  评论(0编辑  收藏  举报