JavaWeb核心之Servlet
一、Servlet简介
1、什么是Servlet
        Servlet 运行在服务端的Java小程序,是sun公司提供一套规范(接口),用来处理客户端请求、响应给浏览器的动态资源。但servlet的实质就是java代码,通过java的API 动态的向客户端输出内容
servlet规范:包含三个技术点(三大组件)
  1. servlet技术
  2. filter技术---过滤器
  3. listener技术---监听器
 
2、Servlet快速入门
实现步骤(必须、缺一不可):
a、创建类实现Servlet接口
b、覆盖尚未实现的方法-----service方法
c、在web.xml进行servlet的配置
 
3、Servlet的API
a、Servlet接口中的方法
(1)init(ServletConfig   config)
何时执行:servlet对象创建的时候执行。
ServletConfig:代表的是该servlet对象的配置信息。
//1.获得servlet的name---<servlet-name>QuickStartServlet</servlet-name>
             String servletName = arg0.getServletName();
             System.out.println(servletName);//QuickStartServlet,配置文件中自己定义的名字
             //2.获得该servlet的初始化的参数
             arg0.getInitParameter(null);
             //3.获取ServletContext对象
             ServletContext servletContext = arg0.getServletContext();
(2)service(ServletRequest request, ServletResponse response)。
何时执行:每次请求都会执行
ServletRequest:代表请求 ,认为ServletRequest 内部封装的是http请求的信息。
ServletResponse:代表响应,认为要封装的是响应的信息。
(3)destroy()
何时执行:servlet销毁的时候执行。
 
4、Servlet的生命周期(面试问题?)
(1)Servlet何时创建
    默认第一次访问servlet时创建该对象(调用init()方法)
(2)Servlet何时销毁
    服务器关闭servlet就销毁了(调用destroy()方法)
(3)每次访问必须执行的方法
public void service(ServletRequest arg0, ServletResponse arg1)
 
面试题:介绍下servlet的生命周期?
 
5、Servlet的执行过程
 
客户端 服务器端(Tomcat服务器) 数据库
 
 
 
 
http://localhost:8888/XXXX
 
 
 
 
 
 
 
 
 
 
 
 
            Tomcat
 
Tomcat引擎
 
1、解析请求的资源地址
2、创建Servlet对象
3、创建代表对象请求的request对象和代表响应的response对象
服务器
 
WEB工程
 
由Tomcat引擎传递request、response。
 
service(request,response)
 
 
每次访问services方法都会创建一对新的request和response对象。
 
问题:对XXXServlet进行了10次访问,init(),destory(),service(),doGet(),doPost()    一共执行力多少次?request对象创建几个?response创建几个?
 
Servlet访问的过程:
Http请求---->web.xml-------->  url -pattern----->servlet-name----->servlet-class----->   QuickStratServlet(对应的Class文件)
 
6、servlet的配置
 
基本配置web.xml文件
<!--servlet的类的配置-->
<!--servlet的虚拟路径的配置-->
其中url-pattern的配置方式:
a、完全匹配:访问的资源与配置的资源完全相同才能访问到
<url-pattern>/quickStartServlet</url-pattern>
b、目录匹配:格式:/虚拟的目录..../*    
<url-pattern>/aaa/bbb/ccc/*</url-pattern>   //*  代表任意
c、扩展名访问:格式:*.扩展名;   
<url-pattern>*.abcd</url-pattern>
 
注意:第二种与第三种混用   如 :/aaa/bbb/*.cba  (错误)
 
服务器启动实例化Servlet配置
Servlet何时创建:默认第一次访问时创建
为什么是默认?
当在Servlet的配置是,加上一个配置<load-onstartup> ;
 servlet对象在服务器启动时就创建。<!--数字代表优先级,数字越小优先级越高-->
<load-on-startup>4</load-on-startup>   最好取中间数字 4/5。
 
缺省Servlet    ?
可以将url-pattern 配置一个/,代表该servlet是缺省的servlet。
什么是缺省的servlet?
    当你访问资源地址所有的servlet都不匹配时,缺省的servlet赋值处理。
其实,web应用中所有的资源的响应都是servlet负责,包括静态资源(html页面)。(有配置缺省的servlet,无法访问到静态资源。)
 
欢迎页面?
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
可以自己设置欢迎页面!
如果自己没有配置,则找全局的web.xml里面的配置信息。
(Tomcat---->conf----->web.xml)
自己添加模板!servlet
 
 注:在实际开发中,基本不用以上方法建立Servlet,但还是需要了解明白其过程。
直接新建---->Servlet
 
7、案例:实现用户登录功能
 
客户端 服务器端 数据库端
登录的页面
用户名
 
密码
 
提交
LoginServlet
doPost(request,response)
//通过request获得请求参数
//使用DBUtils去数据库中校验
//登录成功--显示该用户的所有信息
//登录失败--给错误提示
数据库
 
第一步:创建登录页面login.html
第二步:建立包以及子包
(小技巧:怎样创建子包?Project Explorer工程哪里向下小箭头,点击之后将package presentation调为hierarchical)
第三步:创建数据库连接已经domain(JAVABean)
添加的jar包有:
c3p0-0.9.1.2.jar
commons-dbutils-1.4.jar
mysql-connector-java-5.1.7.-bin.jar
创建:
c3p0-config.xml
DataSourceUtils.java (数据库连接工具)
User.java
第四步:完成Servlet
LoginServlet.java
(注意:如果该类名的话,系统不会自动改哪里使用了该类的类名,特别是配置文档里面的内容。所有一定要手动修改)
 
//1.获得用户名和密码
             PrintWriter out = response.getWriter();
             String username = request.getParameter("username");
             String password = request.getParameter("password");
             
             //2.从数据库中验证该用户名和密码是否正确  
             QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource());
             String sql = "select * from user where username= ? and password = ?";
             User   user = null ;
             try {
                      user = runner.query(sql,new BeanHandler<User>(User.class), username,password);
             } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
             }            
             //3.根据返回的结果给用户不同显示信息
             if (user!=null) {
                    //从servletContext中取出count进行++运算
                    Integer count = (Integer) this.getServletContext().getAttribute("count");
                    count++;
                    
                    //用户登录成功                    
                    response.getWriter().write(user.toString() + "\n  welcome to you " + count +"!!!");
                    this.getServletContext().setAttribute("count", count);
             }else {
                    //用户登录失败
                    response.getWriter().write("sorry your username or password is wrong");
             }
 
8、ServletContext对象(重要)
1、什么是ServletContext对象?
    ServletContext代表一个web应用的环境(上下文)对象。web应用。
  内部封装是该web应用的信息。一个web应用只有一个ServletContext对象。
 
问题:一个web应用中有多少个servelt?------多个
 
ServletContext对象的生命周期?
创建:该web应用被加载(服务器启动或发布应用(前提,服务器是启动状态))
销毁:web应用被加载(服务器关闭,移除该web应用)
 
2、怎样获得ServletContext对象?
a、ServletContext  servletContext = config.getServletContext();
b、ServletContext  servletContext =  this.getServletContext();
//获得ServletContext对象
ServletContext servletContext = this.getServletContext();
 
3、ServletContext的作用
a、获得web应用全局初始化参数
web.xml中配置初始化参数。
 <!--配置全局的初始参数  -->
  <context-param>
       <param-name>driver</param-name>
       <param-value>com.scalpel.login.LoginServlet</param-value>
   </context-param>
通过context对象获得参数
       //获得ServletContext对象
             ServletContext servletContext = this.getServletContext();
             String initParameter = servletContext.getInitParameter("driver");
             System.out.println(initParameter);
 
b、获得web应用中任何资源的绝对路径(重要、重要、重要)
方法: String  path =   context.getRealPath(相对于该web应用的相对地址);
a.txt 在WebContent下:
String  realpath_A = context.getRealPath("/a.txt");
b.txt在WebContent下WEB—INF下面:
String  realpath_B = context.getRealPath("/WEB-INF/b.txt");
c.txt在src下面:
String  realpath_C= context.getRealPath("/WEB-INF/classes/c.txt");
d.txt在WEB13下面:
无法获取。
 
在读取src(classes)下的资源是可以同类加载器---专门加载classes下的文件的。
//getResource()参数是一个相对地址  相对classes
String  path = ContextServlet.class.getClassLoader().getResource("文件名").getPath();
跟c.txt差不多。
 
c、ServletContext是一个域对象(重要  重要  重要)
什么是域对象?什么是域?
存储数据的区域就是域对象
 
ServletContext域对象的作用范围:
整个web应用程序(所有的web资源都可以随意向servletcontext域中存取数据,数据可以共享)
 
统计用户登录次数:
@Override
       public void init() throws ServletException {
             //在ServeltContext域中存一个数据count
             int count = 0;
             this.getServletContext().setAttribute("count", count);
       }      
 
//3.根据返回的结果给用户不同显示信息
             if (user!=null) {
                    //从servletContext中取出count进行++运算
                    Integer count = (Integer) this.getServletContext().getAttribute("count");
                    count++;
                    
                    //用户登录成功                    
                    response.getWriter().write(user.toString() + "\n  welcome to you " + count +"!!!");
                    this.getServletContext().setAttribute("count", count);
 
域对象的通用的方法:
setAtrribute(String name,obj)  存
getAttribute (String name)  取
removeAttribute(String  name)  删除