您的位置:首页 > 大数据

大数据正式18

2017-12-05 18:49 211 查看

大数据正式18

验证码校验

1. regist.jsp中提交的有验证码信息
2. RegistServlet中,验证用户提交的信息和验证码生成时的信息是否一致,并进行相应的处理


验证流程



EasyMall代码改造

ValiImageServlet【把验证码的数据存储到session中】

package com.easymall.ser;

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

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

@SuppressWarnings("serial")
public class ValiImageServlet extends HttpServlet {
// 背景参数
private int base = 30;
private int height = base;
private int width = base * 4;

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 禁止浏览器缓存图片
resp.setHeader("Cache-Control", "no-cache");
resp.setHeader("Progma", "no-cache");
resp.setDateHeader("Expires", 0);
// 创建内存中的图片
BufferedImage di = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
// 获取画布画背景
Graphics2D g2 = (Graphics2D) di.getGraphics();
// 填充矩形
g2.setColor(Color.white);
g2.fillRect(0, 0, width, height);
// 绘制边框
g2.setColor(Color.red);
g2.drawRect(0, 0, width - 1, height - 1);
// 写字并保存到session
String valistr2 = "";
g2.setFont(new Font("微软雅黑", Font.BOLD, 25));
for (int i = 0; i < 4; i++) {
String s = Integer.toString(getRandom(0, 10));
1ba24

valistr2 += s;
g2.setColor(new Color(getRandom(0, 255), getRandom(0, 255),
getRandom(0, 255)));
int temp = getRandom(-45, 45);
g2.rotate(temp / 180.0 * Math.PI, 10 + 30 * i, 20);
g2.drawString(s, 10 + 30 * i, 20);
g2.rotate(-temp / 180.0 * Math.PI, 10 + 30 * i, 20);
}
System.out.println("当前验证码:" + valistr2);
req.getSession().setAttribute("valistr2", valistr2);
// 画干扰线
for (int i = 0; i < 3; i++) {
g2.setColor(new Color(getRandom(0, 255), getRandom(0, 255),
getRandom(0, 255)));
g2.drawLine(getRandom(0, width), getRandom(0, height),
getRandom(0, width), getRandom(0, height));
}
// 画干扰点
for (int i = 0; i < 5; i++) {
g2.setColor(new Color(getRandom(0, 255), getRandom(0, 255),
getRandom(0, 255)));
g2.drawOval(getRandom(0, width), getRandom(0, height), 5, 5);
}
// 画出图片
ImageIO.write(di, "JPG", resp.getOutputStream());
// 关闭画布
g2.dispose();
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doGet(req, resp);
}

// 获取随机数
private int getRandom(int start, int end) {
Random random = new Random();
return start + random.nextInt(end - start);
}

}


RegistServlet【注册逻辑中添加两个验证码数据的校验过程】

package com.easymall.ser;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

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

import com.easymall.exception.MsgException;
import com.easymall.utils.MySqlUtils;

@SuppressWarnings("serial")
public class RegisteSer extends HttpServlet {
private Connection conn = null;
private PreparedStatement stat = null;
private ResultSet rs = null;

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 全局变量
try {
// 0.获取应用参数
ServletContext sc = this.getServletContext();
String encode = sc.getInitParameter("encode");

// 1.解决requestpost请求乱码 解决response输出数据乱码
request.setCharacterEncoding(encode);
response.setCharacterEncoding(encode);
response.setContentType("text/html;charset=" + encode);

// 2.获取请求参数
String username = request.getParameter("username");
String password = request.getParameter("password");
String password2 = request.getParameter("password2");
String nickname = request.getParameter("nickname");
String email = request.getParameter("email");
String valistr = request.getParameter("valistr");

// 验证码校验--获取请求参数的验证码,获取session中的验证码,对比并进行相应的操作
String valistr2 = (String) request.getSession().getAttribute(
"valistr2");
if (valistr == null || valistr2 == null
|| !valistr.equals(valistr2)) {
request.setAttribute("msg", "验证码不正确!");
request.getRequestDispatcher(
request.getContextPath() + "/regist.jsp").forward(
request, response);
return;
}
// 3.检查数据有效性 如果有问题 向浏览器报错
if (username == null || "".equals(username)) {
throw new MsgException("用户名不能为空!");
}

if (password == null || "".equals(password)) {
throw new MsgException("密码不能为空!");
}

if (password2 == null || "".equals(password2)) {
throw new MsgException("确认密码不能为空!");
}

if (!password.equals(password2)) {
throw new MsgException("两次密码不一致!");
}

if (nickname == null || "".equals(nickname)) {
throw new MsgException("昵称不能为空!");
}

if (email == null || "".equals(email)) {
throw new MsgException("邮箱不能为空!");
}

if (!email.matches("^\\w+@\\w+(\\.\\w+)+$")) {
throw new MsgException("邮箱格式不正确!");
}

if (valistr == null || "".equals(valistr)) {
throw new MsgException("验证码不能为空!");
}

// 4.存入数据库
// 判断账号是否重复
conn = MySqlUtils.getConn();
stat = conn.prepareStatement("select * from user where username=?");
stat.setString(1, username);
rs = stat.executeQuery();

if (rs.next()) {// 账号重复
throw new MsgException("账号重复");
} else {// 账号不重复
stat = conn
.prepareStatement("insert into user values(?,?,?,?)");// 账号,密码,昵称,邮箱
stat.setString(1, username);
stat.setString(2, password);
stat.setString(3, nickname);
stat.setString(4, email);
stat.executeUpdate();

}

// 5.向浏览器报告成功 回到主页
response.getWriter().write("注册成功!正在前往主页------>>>");
response.setHeader("refresh", "1;url=" + request.getContextPath()
+ "/index.jsp");
} catch (MsgException e) {
String msg = e.getMessage();
response.getWriter().write(msg);
response.setHeader("refresh", "1;url=/regist.jsp");
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
// 关闭数据库
MySqlUtils.close(conn, stat, rs);
}

}

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

}


数据回显

原理:一次请求,一次响应的Request域对象没有被销毁,也没有被改变

流程

浏览器注册请求【携带一些错误的注册信息存进req域】

服务器进行校验,发现错误,携带需要回显的数据回到注册界面

通过Request域获取需要回显的数据进行显示【此时还是属于注册的一次请求一次响应当中】

流程图



代码改造

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
<head>
<title>欢迎注册EasyMall</title>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" href="css/regist.css" />
<script type="text/javascript" src="js/jquery-1.4.2.js"></script>
<script type="text/javascript">
$(document).ready(
function() {
var canSubmit = true;//提交的标志
//用户名已存在检查(ajax)
$("input[name='username']").blur(
function() {
if ($("input[name='username']").val() != "") {
$.get("/UserNameHasServlet?"
+ $.param({
"username" : $(
"input[name='username']")
.val()
}), function(data) {
if ($.parseJSON(data).hasUser) {
//提示该账户已有
$("input[name='username']")
.next("span").text("用户名重复!");
canSubmit = false;
} else {
$("input[name='username']")
.next("span").text("");
canSubmit = true;
}
});
}
});

//两次密码的一致性检验(失去焦点)
$("input[name='password2']").blur(
function() {
if ($("input[name='password2']").val() != "") {
if ($("input[name='password']").val() != $(
"input[name='password2']").val()) {//密码不一致
$("input[name='password2']").next("span")
.text("密码不一致!");
canSubmit = false;
} else {
$("input[name='password2']").next("span")
.text("");
canSubmit = true;
}
}
});
//检查邮箱的格式是否正确
$("input[name='email']").blur(function() {
var email_Reg = /^\w+@\w+(\.\w+)+$/;
if ($(this).val() != "" && email_Reg.test($(this).val())) {
$(this).next("span").text("");

canSubmit = true;
} else {
$(this).next("span").text("邮箱格式不正确!");
canSubmit = false;
}
});
//验证码切换(点击事件)
$("#yzm_img").click(
function() {
$(this).attr(
"src",
"/ValiImageServlet?time="
+ new Date().getTime());
});
//表单提交事件
$("form").submit(function() {
//判断所有的输入框是否为空
$.each($("input[type!='submit']"), function() {
if ($(this).val() == "") {//密码不一致
$(this).nextAll("span").text("数据不能为空!");
canSubmit = false;
} else {
$(this).nextAll("span").text("");
canSubmit = true;
}
});
return canSubmit;
});
});
</script>
</head>
<body>
<h1>欢迎注册EasyMall</h1>
<form action="/RegisteSer" method="POST" onsubmit="">
<table>
<tr>
<td class="tds">用户名:</td>
<td><input type="text" name="username"
value="<%=request.getParameter("username") == null ? "" : request
.getParameter("username")%>"><span></span>
</td>
</tr>
<tr>
<td class="tds">密码:</td>
<td><input type="password" name="password"><span></span>
</td>
</tr>
<tr>
<td class="tds">确认密码:</td>
<td><input type="password" name="password2"><span></span>
</td>
</tr>
<tr>
<td class="tds">昵称:</td>
<td><input type="text" name="nickname"
value="<%=request.getParameter("nickname") == null ? "" : request
.getParameter("nickname")%>"><span></span>
</td>
</tr>
<tr>
<td class="tds">邮箱:</td>
<td><input type="text" name="email"
value="<%=request.getParameter("email") == null ? "" : request
.getParameter("email")%>"><span></span>
</td>
</tr>
<tr>
<td class="tds">验证码:</td>
<td><input type="text" name="valistr"><img id="yzm_img"
src="/ValiImageServlet" style="cursor: pointer" /><span><font
color="#ff0000"><%=request.getAttribute("msg") == null ? "" : request
.getAttribute("msg")%></font> </span>
</td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="注册用户" /></td>
</tr>
</table>
</form>
</body>
</html>


session的工作原理

重要的session的id号Jsessionid【cookie的键,值为浏览器访问的id值】

服务器通过cookie来保存Jsessionid并作为响应头发送给浏览器存入,下次浏览器再次访问服务器数时,通过Jseeionid找服务器中对应的区域,如果找到则用里面的数据

流程图



Cookie被禁用后--URL重写技术解决

原理:将Jsessionid拼接在url后面

如果禁用Cookie,浏览器就不再基于cookie来保存Jsessionid,在服务器中没有这个Jsessionid则找不到对应的Session

解决这个问题,想办法携带Jsessionid来传给服务器---Url重写

resp.encodeURL(String url)【普通的用这个】

resp.RedirectUrl(String url)【重定向用这个】

使用的优缺点

缺点:所有的地址都要这个改变

优点:即使浏览器禁用Cookie,用户也可以正常访问

一般不进行url重写,因为这个错在用户禁用,可以警示用户,也可以引导用户打开浏览器的Cookie

Cookie和Session的区别

 CookieSession
保存时间:自行设置默认30分钟
位置:客户端保存数据服务端保存数据
影响:有可能随着用户的操作被删除只要不刻意删除对应的数据,在存活期间可以可靠的访问
安全性:不安全,可以翻看记录来获得相关的信息安全,数据保存在服务器端
用途:记住用户名一次会话的信息:验证码

Cookie和Session的使用

数据长时间保存:cookie

安全性的选择:Session

继续JSP的学习

Jsp的指令

格式:<%@ 指令名 若干属性 %>

概述:不产生任何直接的输出,是用来控制jsp解析引擎,如何解析页面中的其他部分内容的

指令

page

功能:声明当前jsp的基本属性,指挥解析引擎如何翻译jsp页面中的其他部分内容

属性:

extends:继承哪个类

language:当前jsp使用的开发语言

import:导包【自动导入的包:lang,javax.servlet.,javax.jsp.】

session:会话对象【禁止自动生成的sesion="false",默认为true】

buffer

autoFlush

errorPage:错误页面

isErrorPage:是否是错误页面【true/false】【会多一个Exception对象】

contentTpye:

pageEncoding:

isELIgnored:是否支持EL表达式

include

格式<%@ include file=""%>

功能:实现页面包含

<html>
...
<html>
...
...
</html>
...
</html>


taglib:引入标签库

补充1:乱码

jsp读取翻译的编码:pageEncoding="编码"【保存文件编码和页面编码一致】

翻译过来的servlet将数据通过Response发送给浏览器【response.setCharacterEncoding("utf-8")】【response.contentType("text/html;charset;utf-8")】这两个相当于:【contentType="text/html;charset=utf-8"】

上面的两个乱码可以合成一个:pageEncoding="编码"

文件保存编码

jsp翻译编码

服务器发送编码

浏览器解析编码



补充2:错误页面

errorPage属性可以配置错误页面,但是太麻烦了给所有的jsp页面

可以在web.xml中配置全局的错误界面

<error-page>
<exception-type></exception>
<location></location>
</error-page>

<error-page>
<error-code></error-code>
<location></location>
</error-page>


配置过全局的错误界面,也配置了具体的,执行具体的

jsp的九大隐式对象【内置的,隐藏的】

jsp直接创建的,可以直接拿来用的

application(ServletContext当前web应用)

config(当前Servlet的配置信息)

out(response.getWriter)

session(会话技术HttpSession)

exception(Exception,如果将isError设置为true,则exception代表前一个错误页面的错误信息)

page(代表Servlet)

pageContext(代表当前页面)

1. 代表当前jsp页面
2. 作为入口参数获取其他八大隐式对象
3. 是一个域对象【request,ServletContext,session,pageContext】
1. 生命周期:访问jsp开始,访问完后销毁
2. 作用范围:当前jsp页面
3. 主要功能:
1. 在当前jsp中共享数据
1. setAttribute(String,Objejct)
2. getAttribute(String)
3. removeAttribute(String)
2. 作为入口对象操作四大作用域对象
1. setAttribute(String name,Objejct obj,int scope)
2. getAttribute(String,int scope)
3. removeAttribute(String,int scope)
4. 对应的域
1. PageContext.APPLICATION_SCOPE
2. PageContext.SESSION_SCOPE
3. PageContext.REQUEST_SCOPE
4. PageContext.PAGE_SCOPE
3. findAttribute(String)
1. 寻找指定的对象
2. 搜寻的顺序【由小到大:pageContext、Request、session、application】
3. 找到返回,找不到返回null
4. 转发pageContext.forward("路径");
5. 包含pageContext.include("路径");


request(请求)

response(响应)

记忆方法:【page,request,response,config,application,session,Exception,out,pageContext】

对应所学:【Servlet,请求,响应,配置,web应用,会话,异常,输出,页面】

补充之jsp、Session、Cookie

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐