Day12 Servlet
来源:互联网 发布:犀牛软件版本分析 编辑:程序博客网 时间:2024/06/05 18:50
1.创建Servlet.
【Servlet的实现的关系】
Servlet :接口
|
GenericServlet :通用的Servlet
|
HttpServlet :HttpServlet
* 编写一个类继承HttpServlet,只需要重写doGet和doPost方法.(此时的web.xml都会给自动配好.)
* 配置
所以以后写自己的servlet不用再去实现servlet类了,直接继承HttpServlet类就可以了.可以大量减少重写的方法和类中的代码量.简洁美观
创建的时候要取消创建构造方法的选框,并且勾选doGet和doPost方法.
注意:
创建的类中的doPost方法中调用了doGet方法,原因是直接在doGet中写代码就行了,不管是Get还是Post请求就都可以执行了,减少代码书写.
此处需要总结一下queryrunner的传参形式与c3p0连接池中的getDataSource方法.其中我们取得连接使用的是getConnection方法,但是此处我们要的是一个datasource对象,工具类中定义方法getDataSource方法直接将ComboDataSource对象返回.
3.面试题:Servlet的生命周期:(重要)
生命周期:就是一个对象从创建到销毁的过程.
Servlet生命周期:Servlet从创建到销毁的过程.
* 何时创建:用户第一次访问Servlet创建Servlet的实例
* 何时销毁:当项目从服务器中移除的时候,或者关闭服务器的时候.
用户第一次访问Servlet的时候,服务器会创建一个Servlet的实例,那么Servlet中init方法就会执行.而且只执行一次.
任何一次请求服务器都会创建一个新的线程访问Servlet中的service的方法.在service方法内部根据请求的方式的不同调用doXXX的方法.(get请求调用doGet,post请求调用doPost).
当Servlet中服务器中移除掉,或者关闭服务器,Servlet的实例就会被销毁,那么destroy方法就会执行.
注意:从servers栏去stoptomcat相当于正常关机,会执行destroy方法中的操作.但是直接在console栏terminate相当于直接拔电源.
4.Servlet的相关的配置(了解:工作中使用不多):
【项目启动时就创建Servlet】
Servlet默认是在第一次访问的时候创建的.现在让Servlet在服务器启动的时候创建好.进行对Servlet的配置: 在web.xml中在<servlet></servlet>标签中配置:
* <load-on-startup>2</load-on-startup> --- 传入正整数,整数越小,被创建的优先级就越高.
单例: 只有1份.
多例:1000人同时访问你的网站,那代码就在内存中复制了1000份,能复制出多份实例.
多例比较好,以后要讲得Springmvc是单例的但都会手动将其变成多例的,Struts则是多例的,这两个框架都是对servlet进行封装.
【url-pattern的配置】
url-pattern配置方式共有三种:
1.完全路径匹配 :以 / 开始 例如: /ServletDemo4 ,/aaa/ServletDemo5 , /aaa/bbb/ServletDemo6
2.目录匹配 :以 / 开始 需要以 * 结束. 例如: /* ,/aaa/* ,/aaa/bbb/*
3.扩展名匹配 :不能以 /开始以 *开始的. 例如: *.do , *.action
4.优先级 完全路径匹配 > 目录匹配 >扩展名匹配
***** 由优先级知,错误的写法 :/*.do 会造成tomcat严重报错.
5.开发中的路径的编写:
相对路径:都是需要找位置相对关系.不能以 /开始的.
* ./ 当前路径 ../上一级目录
* 使用相对路径访问时demo1.html相对于ServletDemo6的位置关系如下:
*http://localhost:8080/day09/demo4-url/demo1.html
*http://localhost:8080/day09/ServletDemo6
所以从demo1.html调到ServletDemo6的路径写成:
<h1>相对路径的访问</h1>
<a href="../ServletDemo6">ServletDemo6</a>
绝对路径:不需要找位置相对关系. 以 /开始的.(以后基本都用绝对路径)
* 绝对路径中分为客户端路径和服务器端路径:(以后都用客户端路径)
*客户端路径一定要加工程名. /day09/ServletDemo6
*服务器端路径不需要加工程名. /ServletDemo6 (只有很少的一部分如转发)
<h1>绝对路径的访问</h1>
<ahref="http://localhost:8080/day09/ServletDemo6">ServletDemo6</a>
<a href="/day09/ServletDemo6">ServletDemo6</a>
6.在登录成功后,页面5秒钟跳转到其他的一个页面.
技术分析:
【使用Http协议中的Refresh头信息】
Refresh之前已经介绍可以定时页面跳转.需要使用程序设置头信息才可以.
【response中设置响应头】
* addHeader(String name,String value); --- 针对一个key对应多个value的响应头.
*addDateHeader(String name,long date);
*addIntHeader(String name,int value);
* setHeader(Stringname,String value); --- 针对一个key对应一个value的响应头.
* setDateHeader(String name,long date);
* setIntHeader(String name,int value);
例如:原来的头信息为: xxx:aaa
使用addHeader(“xxx”,”bbb”); -->xxx:aaa,bbb
使用setHeader(“xxx”,”bbb”); -->xxx:bbb
代码实现:
protected void doGet(HttpServletRequestrequest, HttpServletResponseresponse) throwsServletException, IOException {
try {
// 解决向页面输出中文的乱码问题!!!
response.setContentType("text/html;charset=UTF-8");
If验证登陆成功内的动态资源获取用户昵称及实现5秒后跳转:
if(existUser ==null){
// 登录失败
response.getWriter().println("<h1>登录失败:用户名或密码错误!~</h1>");
}else{
// 登录成功 ,无动态读秒的5秒后跳转页面
方式一: response.getWriter().println("<h3>页面将在5秒后跳转!</h3>");
response.setHeader("Refresh","5;url=/day09/demo5-refresh/index.html");*/
方式二: //立即跳转到有JS实现动态读秒的页面,然后5秒后再跳转
response.setStatus(302);
response.setHeader("Location","/day09/demo5-refresh/success.html");
}
使用JS控制读秒的效果:54321跳转到页面
首先要明确实现倒数计时需要使用静态页面来实现,无法用servlet所以新建一个页面,当登陆成功时立即跳转到这个页面实现倒数计时.这是一个静态页面所以无法实现获取动态资源用
户昵称:
SetStatus()方法设置状态码:其中302码是重定向.
设置头中的location是直接跳转的功能.而且要注意后面的地址前不加url.
<title>Insert titlehere</title>
<scripttype="text/javascript">
var time = 5;
window.onload= function(){
setInterval('changeTime()',1000);
}
function changeTime(){
time--;
document.getElementById("s1").innerHTML =time;
}
</script>
</head>
<body>
<h1>登录成功!</h1>
<h3>页面将在<spanid="s1">5</span>秒后跳转!</h3>
</body>
</html>
7.记录网站的登录成功的人数.
登录成功后,5秒后跳转到某个页面,在页面中显示您是第x位登录成功的用户.
技术分析: ServletContext域对象存取数据
【ServletContext域对象存取数据】需要被用到
***** ServletContext对象存取数据,存的数据都是有一定的作用的范围的.这种对象称为是域对象.
*setAttribute(Stringname , Object)用来向ServletContext中存入数据.
*getAttribute()用来从ServletContext中获取数据.
*removeAttribute()用来从ServletContext中移除数据.
一共有9个域对象:servletContext是一个.
每当有一个人登陆成功的时候这个域对象的值就要+1,
代码实现:
前台数据首先传到UserCountServlet验证登录结果,并且使域对象count累加,
登陆成功再将页面跳转到countServlet页面,读取出count的人数进行浏览器输出.
public class UserCountServletextends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
public void init() throwsServletException {
intcount = 0; // 初始化一个变量count的值为0.
// 将这个值存入到ServletContext中.
this.getServletContext().setAttribute("count",count);
}
protected voiddoGet(HttpServletRequest request, HttpServletResponseresponse) throws ServletException, IOException {
try {
response.setContentType("text/html;charset=UTF-8");
// 1.接收表单提交的参数.
Stringusername =request.getParameter("username");
Stringpassword =request.getParameter("password");
// 2.封装到实体对象中.
Useruser =new User();
user.setUsername(username);
user.setPassword(password);
// 3.调用业务层处理数据.
UserServiceuserService =new UserService();
UserexistUser =userService.login(user);
// 4.根据处理结果显示信息(页面跳转).
if(existUser ==null){
// 登录失败
response.getWriter().println("<h1>登录失败:用户名或密码错误!</h1>");
}else{
// 登录成功,记录次数
intcount = (int)this.getServletContext().getAttribute("count");
count++;
this.getServletContext().setAttribute("count",count);
response.getWriter().println("<h1>登录成功"</h1>");
response.getWriter().println("<h3>页面将在5秒后跳转!</h3>");
response.setHeader("Refresh", "5;url=/day09/CountServlet");
}
public class CountServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected voiddoGet(HttpServletRequest request,HttpServletResponseresponse) throwsServletException, IOException {
// 获得Count的值。
response.setContentType("text/html;charset=UTF-8");
intcount = (int)this.getServletContext().getAttribute("count");
response.getWriter().println("<h1>您是第"+count+"位登录成功的用户!</h1>");
}
理解难点:域对象和定义的变量二者之间的关系,它们可以同名,但是域对象的获取和设置必须通过方法来设置.通过下面老师自写的代码对比加深理解.
8.ServletConfig对象(仅了解):获得Servlet的配置信息.
* String getServletName(); ---获得Servlet在web.xml中配置的name的值.
* String getInitParameter(String name); ---获得Servlet的初始化参数的.
* Enumeration getInitParameterNames(); ---获得所有Servlet的初始化参数的名称.
在web.xml中配置初始化参数,此时是放在ServletDemo7中的<servlet>配置标签中的,所以只有7能访问到, 如果配置参数的<init-param>标签放在<Servlet>标签外那所有的servlet就都可以获取了..
<servlet>
<servlet-name>ServletDemo7</servlet-name>
<servlet-class>com.itheima.a_servlet.ServletDemo7</servlet-class>
<!-- 配置初始化参数 -->
<init-param>
<param-name>username</param-name>
<param-value>root</param-value>
</init-param>
<init-param>
<param-name>password</param-name>
<param-value>123</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
protected void doGet(HttpServletRequest request, HttpServletResponseresponse) throws ServletException, IOException {
ServletConfig servletConfig =this.getServletConfig();
String servletName =servletConfig.getServletName();
System.out.println(servletName);// 获得配置中name的值
String username =servletConfig.getInitParameter("username");
String password =servletConfig.getInitParameter("password");
System.out.println(username+" "+password);// //显示的是root 123
//获得所有Servlet的初始化参数的名称
Enumeration<String>en =servletConfig.getInitParameterNames();
while(en.hasMoreElements()){
String name =en.nextElement();
String value =servletConfig.getInitParameter(name);
System.out.println(name+" "+value);
} // 显示的为 username root
password 123
9.ServletContext:重要
ServletContext的作用:
* 1.用来获得全局初始化参数.(下面讲)
* 2.用来获得文件的MIME的类型.
* 3.作为域对象存取数据.
ServletContext是一个域对象.
*作用范围:整个web工程.
* 创建:服务器启动的时候,tomcat服务器为每个web项目创建一个单独ServletContext对象.(一个web项目仅有一个)
* 销毁:服务器关闭的时候,或者项目从服务器中移除的时候.
* 4.用来读取web项目下的文件.
日后学习重点:mybatis, tomcat优化(面试题) ,
- Day12 Servlet
- day12
- day12
- day12
- day12
- day12
- day12
- day12
- Day12
- day12
- Day12
- day12
- day12
- day12
- day12
- Day12
- day12-笔记
- opencvAX-day12
- java socket-3--多客户端与服务器的交互
- 多个session共享数据如何实现
- MacOS 开发
- LeetCode题解 week2(2)
- Spring Boot第四弹:Spring Boot之@Value和@ConfigurationProperties
- Day12 Servlet
- 文章标题
- 用C语言建立链表并进行基础操作
- Unity前期学习的内容,以及一些可能遇到的问题
- 图像语义分割:从头开始训练deeplab v2系列之四【nyu v2数据集】
- 46muduo库使用示例(五)
- 第三周项目二 建设“顺序表”算法库
- centos启动_某个开机启动的服务有问题导致不能启动
- (青岛站)1011