JavaWeb6.docx
《JavaWeb6.docx》由会员分享,可在线阅读,更多相关《JavaWeb6.docx(31页珍藏版)》请在冰豆网上搜索。
JavaWeb6
0421–JavaWeb之ServletContext对象,会话跟踪技术
王健,549051701
1、今天技术点
1:
Servlet的线程安全问题:
只有当声明的成员变量接收参数时,才会有线程安全问题。
解决方案:
“
1:
最好的方式:
就是将成员变量声明成局部变量。
-速度快。
Servlet也是单例的。
2:
可以在方法上添加同步代码块。
3:
也可以实现SingleThreadModel,此时Servlet将不再是单例的对象了。
packagecn.oracle.thread;
importjava.io.IOException;
importjavax.servlet.ServletException;
importjavax.servlet.SingleThreadModel;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
publicclassThreadDemoextendsHttpServletimplementsSingleThreadModel{
Stringname;
publicvoiddoGet(HttpServletRequestreq,HttpServletResponseresp)
throwsServletException,IOException{
name=req.getParameter("name");
try{
Thread.sleep(3000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
resp.getWriter().print("YOurnameis:
"+name+","+this);
}
}
1:
ServletContext对象。
●ServletContext对象
•一个web项目只有一个ServletContext对象。
•当tomcat启动时,由tomcat创建。
•全局共享数据。
●与所有登录的用户共享数据。
•功能:
•实现聊天。
•实现统计页面的点击量。
•获取本地数据并显示,如图片。
1.2、ServletContext作为另一个域对象
可以保存数据:
所有的域对象:
setAttribute(“name”,Object);保存某个对象。
getAttribute(“name”):
object–获取这个域对象的中的值。
;、
removeAttribute
getAttributeNames
1.3、获取这个域对象的方式:
1:
通过ServletConfig获取这个域对象
ServletContextapplication=ServletConfig.getServletContext();
2:
也可以在Request中获取
ServletContextapplication=request.getSession().getServletContext();
1.4、功能–共享数据
1:
这个程序中,所有的组件中(Servlet,jsp,filter.listener)就可以共享数据
以下是共享数据的基本示例:
代码如下:
先向里面保存数据
publicclassCtx1ServletextendsHttpServlet{
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
response.setContentType("text/html;charset=UTF-8");
PrintWriterout=response.getWriter();
ServletContextapplication=getServletConfig().getServletContext();
if(application.getAttribute("name")==null){
Randomrandom=newRandom();
Stringstr="保存的数是:
"+random.nextInt(1000);
//将这个随机数
application.setAttribute("name",str);
out.print("放成功了:
"+str);
}else{
out.print("已经存在了数据");
}
out.print("window.history.go(-1);'>返回");
}
}
在第二个Servlet中获取数据:
publicclassCtx2ServletextendsHttpServlet{
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
response.setContentType("text/html;charset=UTF-8");
PrintWriterout=response.getWriter();
//直接从ServletContext中获取数据
ServletContextsc=request.getSession().getServletContext();
//获取数据
Stringstr=(String)sc.getAttribute("name");
out.print("22:
"+str);
}
}
1:
保存所有登录的用户共享的数据。
功能1:
计算点击量:
publicclassCountServletextendsHttpServlet{
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
//每一次来访问这个方法,都是点击量+1
ServletContextapplication=getServletContext();
//先从Application中取数据
Integercount=(Integer)application.getAttribute("count");
//如果是第一个人来访问则为null
if(count==null){
count=1;
}else{
count++;
}
//放回到applicatioin
application.setAttribute("count",count);
response.setContentType("text/html;charset=UTF-8");
PrintWriterout=response.getWriter();
out.println("
DOCTYPEHTMLPUBLIC\"-//W3C//DTDHTML4.01Transitional//EN\">");
out.println("");
out.println("
AServlet");
out.println("
");
out.print("这是一个新的信息,。
。
。
。
。
这个新闻被点击了:
"+application.getAttribute("count"));
out.println("");
out.flush();
out.close();
}
}
为了保证数据的原子性,应该同步,但在doGet方法k使用同步又很慢:
就应该考虑开一个线程:
publicclassCountServletextendsHttpServlet{
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
//每一次来访问这个方法,都是点击量+1
finalServletContextapplication=getServletContext();
newThread(){
publicvoidrun(){
newAddOne(application).increment();
};
}.start();
response.setContentType("text/html;charset=UTF-8");
PrintWriterout=response.getWriter();
out.println("
DOCTYPEHTMLPUBLIC\"-//W3C//DTDHTML4.01Transitional//EN\">");
out.println("");
out.println("
AServlet");
out.println("
");
out.print("这是一个新的信息,。
。
。
。
。
这个新闻被点击了:
"+application.getAttribute("count"));
out.println("");
out.flush();
out.close();
}
}
//在这个代码中添加1
classAddOne{
privateServletContextapplication;
publicAddOne(ServletContextsc){
this.application=sc;
}
publicsynchronizedvoidincrement(){
//先从Application中取数据
Integercount=(Integer)application.getAttribute("count");
//如果是第一个人来访问则为null
if(count==null){
count=1;
}else{
count++;
}
//放回到applicatioin
application.setAttribute("count",count);
}
}
功能2:
实现一个聊天程序:
第一步:
开发一个servlet先写出一个表单:
publicclassChatServletextendsHttpServlet{
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
//直接去请求doPost,只有用户第一次来这个页面时才会走这个doGet方法
doPost(request,response);
}
publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
response.setContentType("text/html;charset=UTF-8");
PrintWriterout=response.getWriter();
//1:
写出一个表单
Stringform=""+
"发言:
"+
"";
form+="
";
out.print(form);
}
}
第二步:
生成一个文本域
第三步:
接收参数–完整的代码如下:
packagecn.oracle.count;
importjava.io.IOException;
importjava.io.PrintWriter;
importjava.text.SimpleDateFormat;
importjava.util.Date;
importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
publicclassChatServletextendsHttpServlet{
SimpleDateFormatsdf=newSimpleDateFormat("HH:
mm:
ss");
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
//直接去请求doPost,只有用户第一次来这个页面时才会走这个doGet方法
doPost(request,response);
}
publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
response.setContentType("text/html;charset=UTF-8");
PrintWriterout=response.getWriter();
//1:
写出一个表单
Stringform=""+
"发言:
"+
"";
form+="
";
out.print(form);
//接收参数
request.setCharacterEncoding("UTf-8");
Stringmsg=request.getParameter("msg");
if(msg!
=null&&!
msg.trim().equals("")){//是否为null
//获取用户的ip
Stringip=request.getRemoteAddr();
ip=ip.substring(ip.lastIndexOf(".")+1);
Stringtime=sdf.format(newDate());
msg=ip+"("+time+"):
"+msg;
//将参数放到application,先获取以前有没有人说话
Stringmsgs=(String)getServletContext().getAttribute("msgs");
if(msgs==null){
msgs=msg;
}else{
msgs+="\r\n"+msg;
}
//再放回到app
getServletContext().setAttribute("msgs",msgs);
}
StringmsgBox="300px;height:
400px;'>"
+getServletContext().getAttribute("msgs")
+"";
out.print(msgBox);
}
}
2:
ServletContext获取项目的真实的目录
java.lang.String
getRealPath(java.lang.String path)
ReturnsaStringcontainingtherealpathforagivenvirtualpath.
获取项目的真实的路径。
基本的示例:
publicclassRealpathServletextendsHttpServlet{
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
response.setContentType("text/html;charset=UTF-8");
PrintWriterout=response.getWriter();
out.print("你的项目的真实的路径为:
"+getServletContext().getRealPath("/index.jsp"));
out.print("
你的项目的真实的路径为:
"+getServletContext().getRealPath("/WEB-INF"));
}
}
示例:
显示某个目录下所有的图片:
publicclassImgServletextendsHttpServlet{
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
response.setContentType("text/html;charset=UTF-8");
PrintWriterout=response.getWriter();
//1:
获取这个目录
Stringpath=getServletContext().getRealPath("/imgs");
//2:
构造成一个file对象
Filefile=newFile(path);
//3:
就可以列出这个目录下的所有文件名
String[]fs=file.list();
StringcontextPath=request.getContextPath();
for(Stringnm:
fs){
Stringa="";
Stringimg="3px;border:
0px;'src='"+contextPath+"/imgs/"+nm+"'/>";
img=a+img+"";
out.print(img);
}
}
}
3、获取在web.xml中配置的全局的初始化参数
示例代码:
//先获取sc对象
ServletContextsc=getServletContext();
Stringname=sc.getInitParameter("name");
Stringaddr=sc.getInitParameter("addr");
out.print(name+","+addr);
2、会话技术
a)在服务器上,有一个对象,可以记录某一个特定的用户的状态。
记录用户状态的技术,会话技术。
b)因为网页HTTP协议,HTTP协议是无状态的协议。
2:
会话跟踪技术–session
Session是某个会话(某个浏览器)相关的。
一个会话就是一个session.互不影响。
Session也是一个域对象。
-只与一个用户相关。
示例:
说明session是对某个用户相关的数据:
第一步:
先开发Aservelt
publicclassAServletextendsHttpServlet{
publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
response.setContentType("text/html;charset=UTF-8");
PrintWriterout=response.getWriter();
//设置对post有效的编码
request.setCharacterEncoding("UTF-8");
//接收用户的参数
Stringname=request.getParameter("name");
if(name!
=null&&name.trim().length()>=3){
out.print("你登录成功");
//将用户信息名称放到三个域中去
request.setAttribute("name",name);
//获取Session
HttpSessionsession=request.getSession();
//将用户名称,也放到sesion
session.setAttribute("name