jsp+servlet实现一个简单的登陆功能(无数据库)

登陆功能加入了随机验证码,怎么生成随机验证码的链接点这里

首先给出项目整体图
jsp+servlet实现一个简单的登陆功能(无数据库)
有两个servlet,一个是LoginServlet (控制登陆,验证输入的验证码和用户名密码正确与否),还有一个是VarifyCodeServlet(生成验证码,响应到客户端)

LoginServlet

package cn.edou.servlet;

import java.io.IOException;

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

public class LoginServlet extends HttpServlet {

	/**
	 * 
	 */
	
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//检查验证码是否正确
		String sessionText = (String) request.getSession().getAttribute("sessionText");
		String varifycode = request.getParameter("varifycode");
//		request.setAttribute("code",sessionText);
		if(varifycode.trim().equals("")){
			request.setAttribute("fault", "请输入验证码");
			request.getRequestDispatcher("/session2/login.jsp").forward(request, response);
			return;
			}
		else{
			if(!varifycode.equalsIgnoreCase(sessionText)){
				request.setAttribute("fault", "验证码不正确");
				request.getRequestDispatcher("/session2/login.jsp").forward(request, response);
				return;	
			}
		}
		request.setCharacterEncoding("utf-8");
		//获取表单中的账号和密码,如果账号和密码等于admin,admin则登陆成功
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		if("admin".equals(username)&&"admin".equals(password)){
			//设置Cookie
			Cookie userCookie = new Cookie("name",username);
			userCookie.setMaxAge(60*60*24*7); //one week
			response.addCookie(userCookie);
			//获取session会话,存入账号
			HttpSession session = request.getSession();
			session = request.getSession();
			session.setAttribute("sessionName", username);
			//请求转发到成功页面
			response.sendRedirect("/day11_3/session2/success.jsp");
		}
		else{
			request.setAttribute("fault", "你的用户名或者密码错误");
			request.getRequestDispatcher("/session2/login.jsp").forward(request, response);
		}
	}
	public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{
		doPost(request, response);
	}
}

VarifyCodeServlet

package cn.edou.servlet;


import java.awt.image.BufferedImage;
import java.io.IOException;

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

import cn.edou.image.VerifyCode;

/**
 * Servlet implementation class VarifyCodeServlet
 */

public class VarifyCodeServlet extends HttpServlet {
	
	public void doGet(HttpServletRequest request,HttpServletResponse response){
		//这个功能是把验证码的文本值传到session域,并且返回一张图片
		VerifyCode vc = new VerifyCode(); 
		BufferedImage bi = vc.getImage();
		String text = vc.getText();
		request.getSession().setAttribute("sessionText",text);
		try {
			vc.outputStream(bi, response.getOutputStream());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

然后是显示页面,有两个jsp页面,一个是login.jsp还有一个是success.jsp
login.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'login.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
<!-- 首先得到会话中的错误信息 -->
<%
	String fault="";
	String sessionFault = (String)request.getAttribute("fault");
	if(sessionFault!=null){
		fault=sessionFault;
	}
%>
<!-- 获取Cookie中的username -->
<%
	String name="";
	Cookie[] cookies = request.getCookies();
	if(cookies!=null){
		for(Cookie c:cookies){
			if("name".equals(c.getName())){
				name=c.getValue();
			}
		}
	}
%>
  <body>
   		<form action = "/day11_3/LoginServlet" method="post">
   		<!--获取session域中的fault  -->
   		<%--request.getAttribute("code") --%>
   		<font color="red"><%=fault%></font><br/>
   			用户名:<input type="text" name="username" size="20" value="<%=name%>"/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;:<input type="password" size="20" name="password"/><br/></br>
   			验证码:<input type="text" name="varifycode" size="5"/>
   				<img id="code" src="/day11_3/VarifyCodeServlet" width="120px" height="30px"/>
   				<a href="/day11_3/session2/login.jsp" onclick="change()">换一张</a>
   			<br/><br/>
   			<input type="submit" value="登陆"/>
   		</form>
   		<script type="text/javascript">
   			function change(){
   				var img = document.getElementById("code");
   				img.src = "/day11_3/VarifyCodeServlet";
   			}
   		</script>
  </body>
</html>

success.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'success.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  <%
  	String sessionName = (String)session.getAttribute("sessionName");
  	if(sessionName==null){
  		request.setAttribute("fault", "你还没有登陆,不能访问");
  		request.getRequestDispatcher("/session2/login.jsp").forward(request, response);
  		return;
  	}
  %>
  <body>
    <h1>欢迎<%=sessionName %>,你已经登陆成功</h1>
  </body>
</html>

最后给出VarifyCodeServlet引用的一个VarifyCode.java源代码,其实这个代码在本文最上面给出了,但是这个与哪个有点不同,在那个基础上改进了一下方法
VarifyCode.java

package cn.edou.image;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;

import javax.imageio.ImageIO;

public class VerifyCode {
	//定义一些变量
	private int x = 240;
	private int y = 80;
	private int fontSize = 70;
	private StringBuilder sb = new StringBuilder();
	private String text;
	private Random random = new Random();
	private Color bgColor = new Color(255,255,255);
	private String[] fontsName = {"宋体", "华文楷体", "黑体", "华文新魏", "华文隶书", "微软雅黑", "楷体_GB2312"};
	private String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ";
	//获取随机的字体
	private String getFont(){
		int index = random.nextInt(fontsName.length);
		String fontName = fontsName[index];
		return fontName;
	}
	//获取字母
	private String getChar(){
		int index = random.nextInt(codes.length());
		String ch = codes.charAt(index)+"";
		return ch;
	}
	//获取颜色
	private Color getColor(){
		int red = random.nextInt(150);
		int green = random.nextInt(150);
		int blue = random.nextInt(150);
		return new Color(red,green,blue);
	}
	//设置缓冲区
	private BufferedImage getBufferedImage(){
		BufferedImage bi = new BufferedImage(x,y,BufferedImage.TYPE_INT_RGB);
		Graphics2D pen = (Graphics2D)bi.getGraphics();
		pen.setColor(this.bgColor);
		pen.fillRect(0,0,x,y);
		return bi;
	}
	//给缓冲区添加字符串,添加干扰线
	private BufferedImage addCharAndLine(){
		BufferedImage bi = getBufferedImage();
		Graphics2D pen = (Graphics2D)bi.getGraphics();
		StringBuilder sb = new StringBuilder();
		for(int i=0;i<4;i++){
		String font = getFont();
		int style = random.nextInt(4);
		pen.setColor(getColor());
		pen.setFont(new Font(font,style,fontSize));
	    String s = getChar();
	    sb.append(s);
		pen.drawString(s, 10+i*50, 65);
		}
		this.text=sb.toString();
		int lineNumber = 3;
		pen.setColor(Color.BLUE);
//		pen.setStroke(new BasicStroke(1.5F));
		pen.setStroke(new BasicStroke(1.5F,BasicStroke.CAP_ROUND,BasicStroke.JOIN_MITER));
		for(int i=0;i<lineNumber;i++){
			int x1 = random.nextInt(x);
			int y1 = random.nextInt(y);
			int x2 = random.nextInt(x);
			int y2 = random.nextInt(y);
			pen.drawLine(x1, y1, x2, y2);
		}
		return bi;
	}
	//获取验证码的值
	public String getText(){
		return this.text;
	}
//	public String getText(BufferedImage bi){
//		return sb.toString();
//	}
	//获取一张验证码图片
	public BufferedImage getImage(){
		return addCharAndLine();
	}
	//输出图片
	public void outputImage(BufferedImage bi,String imageName){
		String path = "D:\\JavaWebExercise\\day12\\"+imageName+".jpg";
		try {
			ImageIO.write(bi, "JPEG", new FileOutputStream(path));
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	//输出图片流
	public void outputStream(BufferedImage bi,OutputStream os){
		try {
			ImageIO.write(bi, "JPEG", os);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

我自己在敲代码的时候出现的几个问题,在这总结一下

  1. 路径的问题,重定向以及超链接中的目标路径都是带项目名的,也就是绝对路径,请求转发的路径若是相对路径,以/开头不用给出项目名。给出例子:超链接<a href="/day11_3/session2/login.jsp" onclick="change()">换一张</a>img标签<img id="code" src="/day11_3/VarifyCodeServlet" width="120px" height="30px"/> 重定向response.sendRedirect("/day11_3/session2/success.jsp"); 请求转发request.getRequestDispatcher("/session2/login.jsp").forward(request, response);
  2. 参数存放的域对象是哪个?这里我们设置的参数种类有验证码的参数,以及错误信息的参数,错误信息的参数是在请求时候进行验证的,所以把它放在了request域对象,而在请求login.jsp的时候其实发出了两个请求,一个是请求login的页面,还有一个是请求VarifyCodeServlet,我们为了验证输入验证码的正确与否,需要把正确的验证码存放起来,如果把验证码存放在request域,那么在login页面点登陆,又是一个request,这时候存放在request域的验证码文本已经请求不到了,所以我们把验证码文本存放在了session域。
  3. 在login.jsp页面里面,其中<a href="/day11_3/session2/login.jsp" onclick="change()">换一张</a>这里引用了js事件,change函数如下function change(){ var img = document.getElementById("code"); img.src = "/day11_3/VarifyCodeServlet"; }解释一下,用dom对象获得了id为code的节点(img节点),然后将img结点的src属性改为/day11_3/VarifyCodeServlet,其实这的作用就是在你每次点换一张的时候,可以重新调用VarifyCodeServlet,然后给出老师的代码<a href="javascript:_change()">换一张</a>老师这里用的是javascript伪协议
function _change() {
	/*
	1. 得到img元素
	2. 修改其src为/day11_3/VerifyCodeServlet
	*/
	var imgEle = document.getElementById("img");
	imgEle.src = "/day11_3/VerifyCodeServlet?a=" + new Date().getTime();
}

相关文章: