适用学习 对象 : java的 初学者 仅供参考-----------
开发 工具 idea ---- jdk8 ------ javaEE7 服务器tomcat 8.5
涉及javaWeb 基础 : session request response
有图 有码
分析 需求
:使用jsp来实现的 验证码 的 实现 : login.jsp ------ LoginServlet -----
login.jsp -----------
form table 表单 : tr —td
======& jsp的预览 要在 服务器 里 运行 :
--------- action 的请求的 是 :
servlet :---------- LoginSrevlet ---------
设置请求request的 编码 :
所有的 request 的参数:
获取验证码 ??
将 用户用户的 信息
5 判断 用户
信息的 封装到user 对象 里
session
判断 用户 的 获取 程序 生成验证码 : 与 用户输入 是否 保持一致
先判断 验证码 在 判断 用户 :减少 的 数据库 的访问次数的 压力
if 一致 :
if 用户名与密码
正确就 的登录成功
else
1: 给提示
2: 重定向到登录页面 ========= 重定向
这里 转发到Session 里 也是可以 的
----- 门都 没有进 就得重来 了-------
else 不一致 :
1: 提示验证 错误的 信息
2: 转发 跳转到 登录页面 里 ========= 转发
错误信息 只在jsp 里共享-----v 一次request 里 无需其他人知道
只是 起码都登录 了 验证码的错误
- 涉及
一个转发与 重定向 是的 区别 :
关于request 与的 使用与否
request 域里就会 用转发 其他的就是 重定向
使用 中 路径与否:
转发---相对路径 重定向---绝对路径
---- 关于域对象的 使用场景 :
用户名 与登录 会 经常的使用 存在 Session 里 ------
具体实施 : 将原来 一边写好 验证码的 servlet、 粘贴过来 :
据需要在 的改进 : 使用个的是StringBuild =====
生成 验证码 在Session域 里 域 ------ 操作方法 Attribute
防止空指针异常 ---=========
验证码忽略大小写 -------
-
注意 :
form 表单 提交到servlet 里
先判断 :验证码错误就少判断一次数据库
也许: 可能看不出来的 ------ null 值得判断 :sjp 里直接的就进行的 三元判断式 ******* 用一次就是失效 : 前面一点获取就 后面就会 removeAttribute() 是的 使用
============ 编码的实施 ===============
-
创建前端页面 :
--- from 表单的额 action 到指定的 servlet 里 method= post ---table 表格 里 tr -- td 里input Type与name 的属性的 定义 --- 分别定义的的是 ; ----- ----用户名 type text ----密码 type password ---- 验证码 type text ----img ----td 的 colspan=2 跨2行 ---- 图片 : img 的id =“img” src =“指定的servlet” ---- submit -----value:“登录” td 的 colspan=2 跨2行
-
使用js 来进行 切换 验证码 :
Windows 调用 onload 的回调函数 ‘function(){} 里’
通过id 获取标签体 :getElementById(“img”)onlick=function(){
this 调用当前的获取的标签体的img
调用src 指定的 方法 里 拼接time 值参数 的时间戳 ?time”+:
new Date().getTime()
----- 后端的继续编写 ---------------
创建servlet 页面 :
获取所有请求的参数 :request.getPrimaterMap()
获取Map --- 操作数据库 来做 ======
这不用数据库的操作 ---- 需要你 完善 数据库的
分别 获取参数 的:
request.getParameter(“ username ”) 。。password 。。checkCode。。
---- 因为 是2次请求 : from表单里面 的 增加 验证码 的这次请求
将生成的码值 储存 到 Session 里 ------- 然后 在 loginServlet 里 对比判断 即可
CheckCodeServlet 里 ==========
用StringBuild 的 append( )方法 来咋for 里 进行拼接 ---
--- 用 toString () 转为字符串 :
// 存入session 里 : ----
request.getSession().setAttribute("",""); 键 定义名称 ,
值 就是---- StringBuild 的值
loginServlet 里 :========== 继续
获取Session的 域里 储存的 刚才的 生成 的 验证码 ;
--- request.getSession().getAttribuet("参数名称") ;
----- 返回一个 object对象 强转为 String:
忽略大小写的 的equalsIgnoreCaes(checkCode)
–### 重定向 范围 域 基于Session 域 :
setAttribute(“”username)
--### 重定向 到 成功的页面 : 参数里 ----获取 虚拟路径 的方法 request.getContextPath()+
-----else :
转发的域 基于request 域里 ----- setAttribute()设置键值对的信息 : 转发到登录 页面 :
转发:
request.getRequestDispatcher("").forward();
---- 转发的不写 虚拟路径 :
----- – 写到这里 就要准备 success.jspde信息 : 是 :
<h1><%=request.getSession().getAttribute("user")%>欢迎你</h1> 这里的 user 就是 要储存的 信息
------ 然后 在login.jsp 里 :----------------------------
-----编写的的2个div
获取2次判断 为错误 的 Attribute 里的 信息
效果 : 对于的用户名与 密码名 的 验证码 输入的错误的提示 :
test 测试 : ===============================
要优化的 的是
------ 在login。jsp 里做到的
1:---- null 的显示的 优化 : 使用 三元表达式 在login 的 这 里
三元表达式的 格式 : ?:
----- 2元 以 ? 问号的左右为 前后条件 条件逻辑
----- 的前置成立 就执行 ?问号后面的: 冒号 为else 的条件
2: 验证码的优化 --------
bug描述 : 浏览器里 当前已经登录 后 当我们 建点击浏览器里 后退的 的时候 依然还是可以登录的
3: 然后要设置的 是: 空指针异常的 判断 字符串!=null
=============
完整代码 呈现
前端的代码的 呈现 —============
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script>
window.onload=function () {
document.getElementById("img").onclick=function () {
this.src="/fhw/image01?time="+new Date().getTime();
}
}
</script>
<style>
div{
color:firebrick;
}
</style>
</head>
<body>
<form action="/fhw/loginServlet" method="post">
<table>
<tr>
<td>用户名</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密码</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td>验证码</td>
<td><input type="text" name="checkCode"></td>
</tr>
<tr>
<td colspan="2"><img id="img" src="/fhw/image01"></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="登录"></td>
</tr>
</table>
</form>
<%-- 直接用CSS 获取标签 给红色是的指示 --%>
验证码的servlet ===================
package com.fhw.web.yanzhengma;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/loginServlet")
public class loginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
//response.setContentType("text/html;charset=utf-8");
/* 已知在前端里 请求到 的 参数在request 域 里 在数据库 里直接的 所有的请求 当前不用数据库的 就直接 进行的 */
String username = request.getParameter("username");
String password = request.getParameter("password");
String checkCode = request.getParameter("checkCode");
// 去 CheckCode 使用 改进获取 生成的 验证码 数据存储 到Session里 ===
// 然后在 当前 Session 里获取 到 验证码 进行判断
HttpSession session = request.getSession();
String checkCoder_session = (String) session.getAttribute("check_code");
session.removeAttribute("check_code");// 每次都是一个 新的
// session 与的里获取生成的 验证码 equals 客户端里请求request 域 比较
if (checkCoder_session!=null && checkCoder_session.equalsIgnoreCase(checkCode)){
// 空指针异常的 判断 && 忽略 大小写,的比较
// 验证码正确
// 判断用户的 和密码 是否一致 : else :重定向 到
if ("fhw".equals(username)&&"123".equals(password)){//需要UserDao 到数据库 里
// 登录成功 : 重定向 :
session.setAttribute("user",username);
response.sendRedirect(request.getContextPath()+"/successLogin.jsp");
}else{//登录失败
request.setAttribute("login_error","用户或密码名错误");
//转发到页面
request.getRequestDispatcher("/login.jsp").forward(request,response);
}
}else{// --------登录页面
request.setAttribute("cc_error","验证码错误");
//转发到页面
request.getRequestDispatcher("/login.jsp").forward(request,response);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
this.doPost(request, response);
}
}
登录的loginservlet ===========
package com.fhw.web.yanzhengma;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/loginServlet")
public class loginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
//response.setContentType("text/html;charset=utf-8");
/* 已知在前端里 请求到 的 参数在request 域 里 在数据库 里直接的 所有的请求 当前不用数据库的 就直接 进行的 */
String username = request.getParameter("username");
String password = request.getParameter("password");
String checkCode = request.getParameter("checkCode");
// 去 CheckCode 使用 改进获取 生成的 验证码 数据存储 到Session里 ===
// 然后在 当前 Session 里获取 到 验证码 进行判断
HttpSession session = request.getSession();
String checkCoder_session = (String) session.getAttribute("check_code");
session.removeAttribute("check_code");// 每次都是一个 新的
// session 与的里获取生成的 验证码 equals 客户端里请求request 域 比较
if (checkCoder_session!=null && checkCoder_session.equalsIgnoreCase(checkCode)){
// 空指针异常的 判断 && 忽略 大小写,的比较
// 验证码正确
// 判断用户的 和密码 是否一致 : else :重定向 到
if ("fhw".equals(username)&&"123".equals(password)){//需要UserDao 到数据库 里
// 登录成功 : 重定向 :
session.setAttribute("user",username);
response.sendRedirect(request.getContextPath()+"/successLogin.jsp");
}else{//登录失败
request.setAttribute("login_error","用户或密码名错误");
//转发到页面
request.getRequestDispatcher("/login.jsp").forward(request,response);
}
}else{// --------登录页面
request.setAttribute("cc_error","验证码错误");
//转发到页面
request.getRequestDispatcher("/login.jsp").forward(request,response);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
this.doPost(request, response);
}
}
success 成功 前端页面 :
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1><%=request.getSession().getAttribute("user")%>欢迎你</h1>
</body>
</html>
============== 总结的提问 : ??? 用Session ==============
生成验证码 放到Session 域 里 的 原因 :
每次请求是可以 共享
request 域 i是 : 客户端每次输入的 请求:--- 在request 里 用 parameter ()
?用Attribute 也可以吗 ??????
请求request 参数里的额 验证码: 客户端 === 再 对比 ===
Session 域 服务器 里的servlet 类生成 的验证码:
========= 形成验证的
=============Attribute 与 parameter 的区别 =========
------ Attribute(服务端 属性 : 4个域 中 的信息)
------ parameter(客户端 参数:get方法:URL post 请求是request请求体)
来源:
parameter参数()-----客户端(浏览器)由用户提供的,若是GET方法是从
URL中 提供的,若是POST方法是从请求体(request body)中提供的;
Attribute-属性----服务器端 组件(JSP或者Servlet)利用requst.setAttribute() 设置的
操作:
parameter参数--------值---只能读取不能修改,get读取用request.getParameter();
Attribute属性------值---既可以读取亦可以修改,读取可以使用request.setAttribute(),设置可使用request.getAttribute()
数据:
parameter参数--------String类型看待,并且客户端的参数值只能是简单类型的值,不能是复杂类型,比如对象。
Attribute 属性--------值可以是任意一个Object类型。
共同点
二者的值都被封装在request对象中。
============
request 是在 客户端吗
:============
不是 : request 是 服务器 创建 实现 HttpServlet 的HttpservletRequest类 -- 肯定在 服务端 里
用来 在servlet 页面 ==编写程序 获取客户端 请求 的参数 :
----- 而 response 同样也是这样的
客户端 里Cookie 的都是怎样的 :==========
有Cookie 信息 java web 里 在servlet 页面里 创建的 Cookie
操作Cookie getName setValie Cookie 键,值 setMaxAge()里通过毫秒值的 正数 : 负数 一次性(Cookie的默认, 零0 就是删除
Cookie只能 局限: 存储 字符串, 大小有限 ,信息不安全,
cookie 就是 客户端的 请求 ;-------人机交流的基本就是 字符串 来进行的
写到cookie 在 到Session 的 :
Session 就是 基于Cookie 来的id 来创建 在服务端 的
细致的: 初次请求有了Cookie信息 : 请求 到了 服务端里 服务器会根据 请求里的
cookie id 创建Session 建立本次会话
第一次请求 与 响应就 建立了 本次回话 的初始化
【基于】cookie与Session组成立 web的 会话 :
本次 会话 灰有许多 的请求 与响应(交流) : 每次 有求必应
==