JavaEE--使用Servlet制作登录注册功能

JavaEE–使用Servlet制作登录注册功能

应用驱动学习1今天学习了Servlet的注册与登陆 Request(请求) Response(响应)
后台(服务器)到前端(客户端|浏览器)用响应response 前端(客户端)到后台(服务器)用请求request
怎么样确定是后台(服务器)到前端(客户端):
从后台(服务器)写数据然后要在前端(客户端|浏览器)显示数据 所以后台到前端用响应
怎么样确定是前端(客户端)到后台(服务器):
从前端(客户端|浏览器)写数据要到达后台(服务器)要在服务器显示数据 所以前端到后台用请求
总之一句话 客户端到服务器用请求
服务器到客户端用响应 浏览器也可以代表是客户端
怎么样确定是后台(服务器)到前端(客户端)案例解释:
假设是要从浏览器(客户端)写入数据↓
JavaEE--使用Servlet制作登录注册功能
要到达服务器也就是后台↓
JavaEE--使用Servlet制作登录注册功能
用请求
怎么样确定是前端(客户端)到后台(服务器)案例解释:
假设是要从后台(服务器)写入数据↓
JavaEE--使用Servlet制作登录注册功能
要到达客户端也就是浏览器↓
JavaEE--使用Servlet制作登录注册功能
用响应

学习大纲:
配置默认欢迎页面,并设置两个超链接,一个到注册,一个到登录

------注册-------
(如何访问servlet)
1.创建注册页面,表单包含各项表单项,并将数据提交到后台的Servlet
2.创建处理注册的Servlet,并将该Servlet在web.xml文件中注册

3.注册成功后,给用户一个“注册成功”的反馈

4.中文乱码问题,分方向解决

5.doGet与doPost的应用区别 (重点)
doGet: 安全性低,效率高,只能传文本参数
doPost:安全性高,效率低(通过请求体方式传参),也可传图片,视频等(上传下载)–用得更多

6.注册成功后,给用户一个“注册成功”且会经过几秒钟后自动跳转到登录页面的效果
response.setHeader(“refresh”, “3;url=login.html”);

-----登录------
1.通过注册的账号来登录
需要在注册时,将注册信息存储(List);然后登录时进行判断
2.创建登录页面
3.登录成功或失败都给予反馈,提示“成功”或“失败”后,再自动跳转回相应的页面

4.新增验证码,加强登录的安全性控制
5.添加点击事件,来更改验证码(js来控制,作业)
6.对验证码的正确性进行校验(重点: 全局变量,全局对象,session对象,req对象应用区别)
7.登录成功或失败都给予反馈,如果失败,则直接回到登录页面,并在当前页面给予提示
(通过页面跳转的方式,在此区分重定向和转发的区别,分别以request和session来存储信息)
(重点:提示信息—jsp;重定向和转发区别–request,session)
jsp = html + java
Request的转发与Request重定向的区别:
JavaEE--使用Servlet制作登录注册功能解释:Request(响应)的转发 是由浏览器请求到LoginServlet里的 再由LogiServlet请求到login.jsp 用的是同一个对象 意思就是浏览器先请求LoginServlet(登陆的类)再由LoginServlet自己去请求login.jsp 这就是转发 浏览器只做一次事情

Request重定向 是由浏览器请求到LoginServlet 然后再由浏览器自己去请求logi.jsp 这有两个对象 都是浏览器做事情 做两次事情
JavaEE--使用Servlet制作登录注册功能

后台:

先写一个DB包 里面有DBCenter
//给定一个集合用于存储注册数据

public class DBCenter {
	public  static List<Student> list = new ArrayList<>();  //用集合来存用户名和密码爱好等等
	public static String imgCode;  //写一个验证码
}

再写一个entity包 里面有Student类

private String username;
	private String password;
	private String sex;
	private String[] loves;
	private String province;
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getUsername1() {
		return password;
	}
	public void setUsername1(String username1) {
		this.password = username1;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public String[] getLoves() {
		return loves;
	}
	public void setLoves(String[] loves) {
		this.loves = loves;
	}
	public String getProvince() {
		return province;
	}
	public void setProvince(String province) {
		this.province = province;
	}
	@Override
	public String toString() {
		return "Student [username=" + username + ", username1=" + password + ", sex=" + sex + ", loves="
				+ Arrays.toString(loves) + ", province=" + province + "]";
	}
	public Student(String username, String username1, String sex, String[] loves, String province) {
		super();
		this.username = username;
		this.password = username1;
		this.sex = sex;
		this.loves = loves;
		this.province = province;
	}
	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}
	public String getPassword() {
		// TODO Auto-generated method stub
		return password;
	}
}

再写一个server包 里面有checkServlet类(验证码)LoginServlet(登陆)RegisterServlet(注册)
RegisterServlet(注册):

public class RegisterServlet extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

		//处理乱码:3 doPost的request方向  前端到后台的处理乱码方式
		req.setCharacterEncoding("utf-8");  客户端到后台乱码处理方式
		一般写两种
		//处理乱码:2.doGet/doPost的response方向  服务器到客户端也可以是后台到客户端乱码处理方式
		resp.setContentType("text/html;charset=utf-8"); 后台到客户端乱码处理方式
		//处理乱码: 1.doGet的request方向
		//username = new String(username.getBytes("iso-8859-1"), "utf-8");
		String username = req.getParameter("username");  //得到参数名
		String password = req.getParameter("password");  //得到参数名
		String sex = req.getParameter("sex");  //得到参数名
		String[] loves = req.getParameterValues("loves");  //得到参数名
		String province = req.getParameter("province");  //得到参数名
		//1.判断在集合中,是否有注册的用户名,没有,则可以成功注册,否则,提示已注册
		boolean isExist = false;  //用户名是否存在  先定义一个不存在
		for(Student st:DBCenter.list){   //增强for
			if(username.equals(st.getUsername())){  //判断 username用户名 是否相等
				isExist = true; 等于true 就代表相等 如果相等就直接退出
				break;
			}
		}
		if(isExist){ //判断用户名是否存在 跳转页面 .登录成功或失败都给予反馈,提示“成功”或“失败”后,再自动跳转回相应的页面
			resp.getWriter().write("用户已存在3秒后跳转到注册,或点击<a href='register.html'>注册</a>");
		}else{
			DBCenter.list.add(new Student(username, password, sex, loves, province));
			resp.getWriter().write("注册成功3秒后跳转到登录,或点击<a href='login.jsp'>登录</a>");
			//resp.setHeader("refresh", "3;url=login.jsp"); //三秒后跳转 可以不写
		}
		
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("doPost...");
		doGet(req, resp);
	}
}

LoginServlet(登陆)

public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//处理乱码:3 doPost的request方向
		request.setCharacterEncoding("utf-8");
	//处理乱码:2.doGet/doPost的response方向
		response.setContentType("text/html;charset=utf-8");
		//设置参数
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		//判断验证码
		//方式1: 获取全局变量存储的验证码---如果多个客户端访问则会出问题
		//String imgCode = DBCenter.imgCode;
		
		//方式2: 从context属性中取出验证码---如果多个客户端访问则会出问题
		//ServletContext context = request.getSession().getServletContext();
		//String imgCode = (String)context.getAttribute("code");
		
		//方式3:用request取出验证码----不同的request得不到验证码(有问题)因为不是同一个对象不是同一个request
		//String imgCode = (String) request.getAttribute("code");
		
		//方式4: 用session取出验证码---OK 一般用这种  获取验证码属性
		String imgCode = (String) request.getSession().getAttribute("code");
		
		String code = request.getParameter("code");  //得到参数名
		 
		if(!code.equals(imgCode)){ //判断 如果验证码里 的内容不等于 输入的内容
			response.getWriter().write("验证失败~~~"); //那么就响应(回答) 验证失败
			return;
		}
		
		//判断用户名和密码
		boolean isSuccess = false;
		for(Student st:DBCenter.list){
			if(username.equals(st.getUsername())&&password.equals(st.getPassword())){
				isSuccess = true;
				break;
			}
		}
		if(isSuccess){
			response.getWriter().write("登录成功!");
		}else{
response.getWriter().write("登陆失败");
			//方式1: session+转发(问题:浏览器不关,则session一直存在)
			request.getSession().setAttribute("msg", "session+转发:登录失败~~");
			request.getRequestDispatcher("login.jsp").forward(request, response);
				
			//方式2:session+重定向(问题:浏览器不关,则session一直存在)
			//request.getSession().setAttribute("msg", "session+重定向:登录失败~~");
			//response.sendRedirect("login.jsp");
			
			//方式3:request+重定向(问题:前端获取不到属性值)
			//request.setAttribute("msg", "request+重定向:登录失败");
			//response.sendRedirect("login.jsp");
			
			//方式4:request+转发(最有效果的提示)
			//request.setAttribute("msg", "request+转发:登录失败");
			//request.getRequestDispatcher("login.jsp").forward(request, response);
		}
		
	}


	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("login doPost");
		doGet(request, response);
	}

}

checkServlet(验证码)

public class checkServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
   
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//1,获取缓存图片对象 设置高度 宽度  RGB红绿蓝的绘制图形
		int width=80;
		int height =50;
		BufferedImage  image=new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		//获取图像缓存区对象
		//2.通过图片对象(image),获取到画笔对象,设置好颜色后,填充区域 
		Graphics graphics =image.getGraphics();//获取图片对象
		graphics.setColor(Color.BLUE);//用图片对象设置背景蓝色 
		graphics.fillRect(0, 0, width, height); //用图片对象 填充长方形 高度和宽都为0
		 //3.设置随机的4个数字 以及干扰线,设置字体颜色
		Random random=new Random(); //获取随机对象
		graphics.setColor(Color.YELLOW);//设置字体为黄色
		StringBuilder sb =new StringBuilder();//拼接验证码  动态字符串 
		graphics.setFont(new Font("宋体", Font.BOLD, 26)); //设置字体 为 宋体    粗体 字体大小26;
		for(int i=0;i<4;i++){
			int nCode=random.nextInt(10);//生成一到10直接的数字
			graphics.drawString(nCode+"", i*15+15, 30);  //设置字体在方框中的宽和高
			sb.append(nCode); //把随机获取的四个数字 拼接起来
		}
		//方式1:用全局变量接收验证码--全局变量全局有效(有问题) 另外一个客户端进去 会改变原有的验证码的值
		//DBCenter.imgCode = sb.toString();  //获取图片验证码
		
		//方式2: 使用context接收验证码---全局对象全局有效(有问题)
		//ServletContext context = request.getSession().getServletContext();
		//context.setAttribute("code", sb.toString());
		
		//方式3: 使用request接收验证码---有问题  因为不是同一个对象不是同一个request
		//request.setAttribute("code", sb.toString());
		
		//方式4: 使用session接收验证码---OK  使用它接受验证码  那么 就可以同时打开多个客户端(浏览器)获取验证码  //如果有另一个客户端访问,则与该客户端session对象独立--类似成员属性
		request.getSession().setAttribute("code", sb.toString());//请求 设置验证码属性
		//5.设置干扰线 10条
		for(int i=0;i<10;i++){
			graphics.drawLine(random.nextInt(width), random.nextInt(height),
					random.nextInt(width), random.nextInt(height));//高和宽各生成一个点两点一线 随机生成线条
		
		}
		ImageIO.write(image, "jpg", response.getOutputStream()); //将绘制好的图片显示到前端
	}
	

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

}

系统登陆 login.jsp格式 jsp=html+java

<body>	
	<%
	   /* 在此处可以写java代码 */
	   String msg = (String)session.getAttribute("msg");
	   //String msg = (String)request.getAttribute("msg");
	   System.out.println(msg);
	%>
	
	<%=(msg==null)?"":msg%>
		

	 <h2>系统登录</h2>
	<form action="LoginServlet" method="post">
	 	用户名:<input type="text" name="username" value="zs" /><br/>
	 	密码:<input type="password" name="password" value="123" /><br/>
	 	验证码:<input type="text" name="code" />
	 	<img src="CheckServlet" alt="未显示" /><a href="#">看不清</a><br/> 
	 	<input type="submit" value="登录" />     
	 </form>
</body>

系统注册 register.thml

<body>
	 <h2>系统注册</h2>
	 <!-- method: 请求方式默认为get -->
	 <form action="RegisterServlet" method="post">
	 	用户名:<input type="text" name="username" value="zs" /><br/>
	 	密码:<input type="password" name="password" value="123" /><br/>
	 	性别:<input type="radio" name="sex" value="man" />男
	 	    <input type="radio" name="sex" value="woman" checked="checked" />女<br/>
	 	爱好:<input type="checkbox" name="loves" value="basketball" />篮球   
	 	    <input type="checkbox" name="loves" value="football" checked="checked" />足球<br/>
	 	省份:<select name="province">
	 			<option value="hunan">湖南</option>
	 			<option value="hubei" selected="selected">湖北</option>
	 			<option value="guangdong">广东</option>
	 			<option value="guangxi">广西</option>
	 	    </select><br/> 
	 	<input type="submit" value="提交" />     
	 </form>
</body>