Session的时效性——由验证码引出的问题
Session的时效性——由验证码引出的问题 (对jsp servlet tomcat 的理解)目录Session的时效性——由验证码引出的问题 11、理解JSP、servlet、web容器 11.1、Jsp 11.2、Servlet 31.3、Web容器 62、好了,当一切准备工作做完,来看一个结合三者的例
Session的时效性——由验证码引出的问题
(对jsp servlet tomcat 的理解)
目录
1、理解JSP、servlet、web容器
1.1、Jsp
JSP也是一个servlet,sun公司是先设计出servlet后,因为其表达视图不方便,又推出servlet
1、它有<%%> 和<!% %> <%=%> 标记和html标记 。
2、JSP九大隐含对象:
request HttpServletRequest类的实例
response HttpServletResponse类的实例
out PrintWriter类的实例,用于把结果输出至网页上
session HttpSession类的实例
application ServletContext类的实例,与应用上下文有关
config ServletConfig类的实例
pageContext PageContext类的实例,提供对JSP页面所有对象以及命名空间的访问
page httpJspPage类的实例,类似于Java类中的this关键字
Exception Exception类的对象,代表发生错误的JSP页面中对应的异常对象
3、还有一些标签库 如 核心标签库,c标签库等
但是万变不离其宗,当你理解到所有的jsp标签代码都能以servlet的形式写出来后,一切就豁然开朗了
一个jsp例子(myeclipse自动生成的)
test.jsp
<%@pagelanguage="java"import="java.util.*"pageEncoding="ISO-8859-1"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPEHTMLPUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<%!int a=1;%>
<%int b=1;%>
<%=a+b%>
</head>
<body>
This is my JSP page.<br>
</body>
</html>
1.2、Servlet
Servlet是java的一系列衍生类,可以狭义的理解为其他java类 Math 类等。它extends HttpServlet 类
不得不说它的创建过程
Init()初始化
doPodst()调用方法
doGet()调用方法
destroy()销毁方法
下面贴一个与上面jsp完全一模一样的servlet对应代码
test.java
package user;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*Servlet implementation class test
*/
@WebServlet("/test")
publicclass testextends HttpServlet {
privatestaticfinallongserialVersionUID = 1L;
inta=1;//标记2
/**
*@see HttpServlet#HttpServlet()
*/
public test() {
super();
//TODO Auto-generated constructor stub
}
@Override
publicvoid destroy() {
//TODO Auto-generated method stub
super.destroy();
}
@Override
publicvoid init() throws ServletException {
//TODO Auto-generated method stub
super.init();
}
/**
*@see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protectedvoid doGet(HttpServletRequest request, HttpServletResponseresponse)throws ServletException, IOException {
//TODO Auto-generated method stub
intb=1; //servlet标记1
PrintWriterout =response.getWriter();
out.print(a+b);//标记3
}
/**
*@see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protectedvoid doPost(HttpServletRequest request, HttpServletResponseresponse)throws ServletException, IOException {
//TODO Auto-generated method stub
doGet(request,response);
}
}
1.3、Web容器
看到这里读者不了解的也许一头雾水,接下来仍要理解一个概念,web容器,我所写的没有废话,当这三个概念写完后,我会将三者利用代码详细解释一下web应用程序的过程
Web容器:目前所接触的只有tomcat,要理解web容器,先理解容器是什么
Jvm就是一个容器,它把java文件编译成 字节码文件class 然在jvm(java虚拟机中运行)
这就是一个容器, 运行所有java文件的容器。
再细分,简单的容器,莫过于List Set这些collection,按规则用来装数据的工具。
tomcat这样级别的容器,它不仅是装数据了,而且可以产生一些特殊的对象(servlet),让这些对象生存,工作,改变,死亡,并且负责容器和外部服务,或者外部程式的各种相关服务。
而上网的基本原理就是,通过浏览器,发送请求给服务器,得到服务器回应的内容。
但有了web容器,就不用担心浏览器透过http协议传到服务器,是怎么接收,解析这些从网络另外一端传输过来的二进制码;也不用关心,那么多的请求,开发人员该怎么去限制连接数量。这些程式,web容器都已经帮应用开发的人员写好了。应用开发的人员只要舒服的去关注,业务的开发,然后把业务程式部署到web容器里就好了。
web容器具体的工作如下:
1。当web服务器接到http请求后,把http协议转给web容器去解析。
2.web容器创建 HttpServletRequest、HttpServletResponse、HttpSession等对象。
3. Web容器由請求的URL決定要使用哪个Servlet來处理請求(事先由开发人員定义)。
4. Servlet根据请求对象(HttpServletRequest )的信息決定如何处理,透过回应对象(HttpServletResponse )來建立回应。
5 . Web容器与Web服务器接通,Web服务器将回应转化为HTTP回应并传回客戶端。
2、好了,当一切准备工作做完,来看一个结合三者的例子
以上过程一定理解!重要重要重要!
3、好,到此为止 一切准备工作做好了。
进入咱们的正题,web加验证码的session 问题
验证码源码
package user;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
importjava.io.PrintWriter;
import java.util.Random;
import javax.imageio.ImageIO;
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;
/**
*Servlet implementation class test
*/
@WebServlet("/test")
publicclass testextends HttpServlet {
privatestaticfinallongserialVersionUID = 1L;
inta=1;
/**
*@see HttpServlet#HttpServlet()
*/
public test() {
super();
//TODO Auto-generated constructor stub
}
@Override
publicvoid destroy() {
//TODO Auto-generated method stub
super.destroy();
}
@Override
publicvoid init() throws ServletException {
//TODO Auto-generated method stub
super.init();
}
/**
*@see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protectedvoid doGet(HttpServletRequest request, HttpServletResponseresponse)throws ServletException, IOException {
//TODO Auto-generated method stub
response.setContentType("image/jpeg");
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires", 0);
HttpSessionsession =request.getSession();
//在内存中创建图象
intwidth = 75,height = 25;
BufferedImageimage =new BufferedImage(width,height,
BufferedImage.TYPE_INT_RGB);
//获取图形上下文
Graphicsg =image.getGraphics();
//生成随机类
Randomrandom =new Random();
//设定背景色
g.setColor(getRandColor(200, 250));
g.fillRect(0, 0,width,height);
//设定字体
g.setFont(new Font("Times New Roman", Font.PLAIN, 24));
//画边框
g.setColor(getRandColor(160, 200));
g.drawRect(0, 0,width - 1,height - 1);
//随机产生155条干扰线,使图象中的认证码不易被其它程序探测到
g.setColor(getRandColor(160, 200));
for (inti = 0;i < 155;i++) {
intx =random.nextInt(width);
inty =random.nextInt(height);
intxl =random.nextInt(12);
intyl =random.nextInt(12);
g.drawLine(x,y,x +xl,y +yl);
}
//取随机产生的认证码(4位数字)
StringsRand ="";
for (inti = 0;i < 4; i++) {
Stringrand = String.valueOf(random.nextInt(10));
sRand +=rand;
//将认证码显示到图象中
g.setColor(new Color(20 +random.nextInt(110), 20 +random
.nextInt(110), 20 +random.nextInt(110)));
//调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
g.drawString(rand, 13 *i + 14, 20);
//将认证码存入SESSION
session.setAttribute("vcode",sRand);
}
//图象生效
g.dispose();
//输出图象到页面
ImageIO.write(image,"JPEG",response.getOutputStream());
}
/**
*@see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protectedvoid doPost(HttpServletRequest request, HttpServletResponseresponse)throws ServletException, IOException {
//TODO Auto-generated method stub
doGet(request,response);
}
Color getRandColor(intfc,intbc) {//给定范围获得随机颜色
Randomrandom =new Random();
if (fc > 255)
fc = 255;
if (bc > 255)
bc = 255;
intr =fc + random.nextInt(bc -fc);
intg =fc + random.nextInt(bc -fc);
intb =fc + random.nextInt(bc -fc);
returnnew Color(r, g, b);
}
}
是一个servlet, 部署好项目并运行后
在地址栏输入 http://localhost:8080/test/test 会出现一张图片
先理解其过程
1、运行的是一个servlet,只不过设置返回结果为图片的形式。
2、但是其中有一行代码
session.setAttribute("vcode",sRand);
请注意,是在生成图片的时候,往sessionsetAttribute的
如果一个 test2.jsp文件中有以下代码
<% String str=(String)session.getAttribute("vcode");%>
<%=str%>
<ahref="#">
<imgalt="验证码"src="test/test"class="checknum"></a>
此时test2.jsp会在web容器中执行<% String str=(String)session.getAttribute("vcode");%>
<%=str%>代码,
此时session中当然没有验证码了,
当web全部转化为静态代码后,浏览器才会继续去访问test/test这个servlet
也就是说,是先getAttribute("vcode")然后才setAttribute的,就会出现一个session时效性问题。
理解了原理,解决这个问题就有方法了!
解决这个问题的方法有三种
1、使用ajax技术在页面全部加载后,重新session中获取。
2、使用JavaScript动态加载机制
3、想办法将加载的图片下载到本地,然后再链接到图片!
至于方法实现,明天写!今天先这样!
2016年12月17日22:56:10
一切都来得及,一切不都会太晚!
2017年3月27日16:47:09 过了3个月了,还没实现当初说的,不过发现一篇更清晰的博客,推荐看看
http://www.bysocket.com/?p=518 泥瓦匠!
QQ:570221322 ,欢迎交流!
更多推荐
所有评论(0)