JavaEE--使用Servlet制作登录注册功能
JavaEE–使用Servlet制作登录注册功能
应用驱动学习1今天学习了Servlet的注册与登陆 Request(请求) Response(响应)
后台(服务器)到前端(客户端|浏览器)用响应response 前端(客户端)到后台(服务器)用请求request
怎么样确定是后台(服务器)到前端(客户端):
从后台(服务器)写数据然后要在前端(客户端|浏览器)显示数据 所以后台到前端用响应
怎么样确定是前端(客户端)到后台(服务器):
从前端(客户端|浏览器)写数据要到达后台(服务器)要在服务器显示数据 所以前端到后台用请求
总之一句话 客户端到服务器用请求
服务器到客户端用响应 浏览器也可以代表是客户端
怎么样确定是后台(服务器)到前端(客户端)案例解释:
假设是要从浏览器(客户端)写入数据↓
要到达服务器也就是后台↓
用请求
怎么样确定是前端(客户端)到后台(服务器)案例解释:
假设是要从后台(服务器)写入数据↓
要到达客户端也就是浏览器↓
用响应
学习大纲:
配置默认欢迎页面,并设置两个超链接,一个到注册,一个到登录
------注册-------
(如何访问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重定向的区别:
解释:Request(响应)的转发 是由浏览器请求到LoginServlet里的 再由LogiServlet请求到login.jsp 用的是同一个对象 意思就是浏览器先请求LoginServlet(登陆的类)再由LoginServlet自己去请求login.jsp 这就是转发 浏览器只做一次事情
Request重定向 是由浏览器请求到LoginServlet 然后再由浏览器自己去请求logi.jsp 这有两个对象 都是浏览器做事情 做两次事情
后台:
先写一个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>