Day12 Servlet

来源:互联网 发布:犀牛软件版本分析 编辑:程序博客网 时间:2024/06/05 18:50

1.创建Servlet.

【Servlet的实现的关系】

Servlet                  :接口

   |

GenericServlet       :通用的Servlet

   |

HttpServlet            :HttpServlet

* 编写一个类继承HttpServlet,只需要重写doGetdoPost方法.(此时的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的实例,那么Servletinit方法就会执行.而且只执行一次.

任何一次请求服务器都会创建一个新的线程访问Servlet中的service的方法.service方法内部根据请求的方式的不同调用doXXX的方法.(get请求调用doGet,post请求调用doPost).

Servlet中服务器中移除掉,或者关闭服务器,Servlet的实例就会被销毁,那么destroy方法就会执行.

 

注意:servers栏去stoptomcat相当于正常关机,会执行destroy方法中的操作.但是直接在consoleterminate相当于直接拔电源.

 

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优化(面试题) , 



























































原创粉丝点击