java学习第30天Servlet

servlet是我们学习的第一个动态资源

1、servlet干什么用的?
    处理请求,生成响应
2、我们如何创建一个servlet呢?
    1>我们只需实现servlet接口即可
    2>继承javax.servlet.http.HttpServlet
    3>继承javax.servlet.http.HttpServlet
3、Servlet的生命周期的方法
        生命周期指的是,必须要经历的过程
        1、出生===>init方法,在构造方法调用之后  调用
        2、使命===>service方法,当请求发来时,处理请求使用
        3、销毁===>destroy方法,当服务器关闭时,会小会servlet,在销毁之前调用该方法释放资源
生命周期:
1、浏览器发送请求
2、服务器分析请求,请求哪个主机哪个项目
3、查找项目下的web.xml是否存在 比如AServlet.java
4、如果是第一次访问,创建servlet实例
5、调用servlet中的init方法,将sevlet实例存储到内存中
6、调用service方法处理请求,将request和respons传递
7、将request和response还给服务器
8、服务器将response组装成http响应协议
9、将http响应协议发送给客户端
servlet中的其他方法
    getServletInfo



4.Servlet中的其他方法.
    getServletInfo ==> 获得servlet的信息(版本,作者,版权..),没用.
    getServletConfig ==> 返回servletConfig对象.

5.ServletConfig对象是什么?
    封装了servlet在web.xml中的配置.
    方法:
        1>getServletName ==> 获得配置文件中 <servlet-name> 元素的内容
        2>getInitParameter ==> 根据 <init-param>中的 <param-name> 获得 </param-value>
            <init-param>
                <param-name>name</param-name>
                <param-value>tom</param-value>
            </init-param>
        3>getInitParameterNames 返回所有<param-name> .
        4>getServletContext(下午讲)
6.其他实现server的方式
        GenericServlet:
            1.帮我们妥善的保管ServletConfig对象
            2.实现了ServletConfig接口 ==> 为调用方便
            注意: 不要重写servlet接口中的 init方法.  不然 第一步优化就白做了. 
                我们要做初始化的动作,需要去重写GenericServlet提供的空参init方法.
        HTTPServlet:
            1.因为我们web项目基于HTTP协议,所以Service方法中传过来的request,response对象都是 基于HTTP协议的. 
                也就是HttpServletReueqst,也就是HttpServletResponse. 它帮我们进行了强转.
            2.我们有可能在不同的请求方式时做不同的事情. 根据请求方式不同,调用不同的方法 
            例如 GET --> doGet()
                 POST ==> doPost();


7、Servlet中的其他细节
1>关于Servlet线程安全问题
    因为在servlet运行期间只有一个servlet实例存在,可能会同时处理多个请求
    那么我们在servlet中声明成员变量来存储用户数据是有线程安全问题的
    我们应该如何解决呢?
        1、实现SingleThroadModel(不推荐了)
        2、使用局部变量保存用户数据(推荐使用)
2>关于servlet随着项目的启动而创建
使用<load-on-startup>配置来实现
    例如:
        <servlet>
          <servlet-name>FServlet</servlet-name>
          <servlet-class>my.servletlearn.thread.FServlet</servlet-class>
          <load-on-startup>这里填写一个整数</load-on-startup>
      </servlet>
      整数越小优先级越高,启动顺序按照配置顺序,如果优先级一样,启动顺序按照配置顺序
3>关于Servlet路径配置问题详解
<url-pattern>
    路径匹配:
        /AServlet     http://localhost:8080/MyWeb/FServlet
        /ABC/AServlet     http://localhost:8080/MyWeb/ABC/FServlet
        /ABC/ABC/*   http://localhost:8080/MyWeb/ABC/ABC/默认
        /*   http://localhost:8080/MyWeb/默认
        /相当于/*

    后缀名匹配:
        *.do==>structs 1  
        *.action ==>structs 2  
        *.html==>  
注意:1、关于路径。配置的路径范围越大优先级越低
2、两种匹配模式不能混用,例如错误的例子: /*.do
4>关于tomcat目录下的web.xml
    1default servlet的配置  404
    2、jsp    servlet的配置
    3、<session-config>
        <session-timeout>30</session-timeout>
      </session-config>
     4、互联网中所有的mime类型
     5、欢迎页面配置
     -----------------------------------------------------------------------
     相关对象之------ServletContext
     1、获得:servletConfig======>getServletContext

     2、servletContext封装了web.xml中的配置
            1> servletContext 封装了web.xml 中的配置
            <context-param>
                <param-name>name</param-name>
                <param-value>jerry</param-value>
            </context-param>
            <context-param>
                <param-name>password</param-name>
                <param-value>1234</param-value>
            </context-param>

                    getInitParameterNames();  ==> 获得所有键
                    getInitParameter(key);  ==> 根据键获得对应的值
         2>serlet技术中3大域对象之一
            ServletContext对应着Application(应用)域.利用了一个项目中只有一个ServletContext实例的特点.在servletContext中放置了一个map用作数据通信.
            这个Map就是所谓域.
                关于域的操作,有4个.
                    放入键值对 setAttribute(key,value)
                    通过键取值 getAttribute(key)
                    通过键删除 removeAttribute(key)
                    遍历所有键 getAttributeNames()
                application ==> servletContext
                session ==> 
                request ==> 
        3>获得项目中资源
    3、servlet技术中对象的范围
        servlet ==>项目启动期间一个servlet只有一个servlet实例
        request===>项目启动期间,request对象的数量,要看当前有多少个请求正在处理
        response ===>同上
        servletConfig ===>一个servlet实例对应一个servletConfig对象
        servletContext===>整个项目中,永远只有一个servletContext实例存在
servlet ==>  server applet ==> 服务器端的小程序

1.作用是用来处理请求(request),完成响应(response)的.

2.如何创建一个servlet
    *实现servlet接口
    *继承GenericServlet
    *继承HttpServlet

3.servlet接口中的方法
    *init (ServletConfig )
    *service (ServletRequest , servletResponse )
    *destory ()
//=======
    *getServletConfig
    *getServletInfo

4.ServletConfig 的 作用.
    *getServletName
    *getInitParameter()
    *getInitParameterNames()
    *getServletContext()
5.servlet线程是不安全的.
    因为在服务器中,一个servlet只存在一个实例.所以当有多个请求同时访问的时候,如果使用成员变量接受线程参数,就会有问题.
    解决办法: 使用局部变量接受线程参数.
6.url-pattern
    路径匹配:   "/"开头  例如: /AServlet 
    后缀名匹配:  "*"开头 例如: *.do
注意: 1.匹配范围越广优先级越低
      2.两种匹配方式不能同时使用.
7.load on  startup
    该配置可以让servlet在服务器启动时加载.
    填入的数字表示优先级.数字越小,优先级越高.
    优先级一样,按配置顺序加载.
8.servletContext 
    范围: 一个项目对应一个servletContext.
    获取: 通过servletConfig获取
    作用: 
        1.获得配置文件(web.xml根下的)中的参数
            *getInitParameter()
            *getInitParameterNames()
        2.域的功能 => application
            增加一个:setAttribute
            删除一个:removeAttribute
            获得一个: getAttribute
            获得所有键: getAttributeNames
        3.获得项目内资源
            getResourceAsStream
            getRealPath
        *以上两个方法都是填写相对路径. "/" ==> 项目的根下(WebRoot)
package my.servletlearn.context.resource;

import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class KServlet extends HttpServlet{

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
/*//        获得资源的其他方式
//      使用class方法
//      "/"  ===>代表classes目录
        InputStream is2=this.getClass().getResourceAsStream("Student.xml");
        // "" ===> 不加 "/",代表当前文件所在目录
        InputStream is3=this.getClass().getResourceAsStream("student/xml");
        System.out.println(is2);
        System.out.println(is3);*/
        //---------------------------------------------------------------------------
        InputStream is4=this.getClass().getClassLoader().getResourceAsStream("");
//      区别就是不加"/" 还是相对于classes目录
        InputStream is5=this.getClass().getClassLoader().getResourceAsStream("/");
        System.out.println(is4);
        System.out.println(is5);
//      获得路径
        String path=this.getClass().getResource("student.xml").getPath();
        System.out.println(path+"path");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        super.doPost(req, resp);
    }

}
package my.servletlearn.context;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.sun.xml.internal.ws.api.policy.PolicyResolver.ServerContext;

public class GServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
//      获得全局init param设置
//      1、获得ServletContext
        ServletContext sContext= getServletContext();
//      调用getXXX方法
        Enumeration<String> enumeration=sContext.getInitParameterNames();
        while (enumeration.hasMoreElements()) {
            String key = (String) enumeration.nextElement();
            String value=sContext.getInitParameter(key);
            resp.getWriter().print(key+"===>"+value+"<br/>");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        super.doPost(req, resp);
    }

}
package my.servletlearn.context;

import java.io.IOException;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HServlet extends HttpServlet{

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        Constant.str="Hello";
//      向静态变量赋值
//      resp.getWriter().print(Constant.str);
//      向女神送包
        Constant.obj="Lv";
//      resp.getWriter().print(Constant.obj);
        Constant.map.put("bag", "Lv");
        Constant.map.put("car", "QQ");
        Constant.map.put("phone", "ventu");
//      使用ServletContext完成通信
//          1、获得ServletContext对象
        ServletContext sc=getServletContext();
//      操作map
        sc.setAttribute("ck", "calkin");
        sc.setAttribute("eat", "jinqiangyu");
        sc.setAttribute("car", "BMW");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        super.doPost(req, resp);
    }

}
package my.servletlearn.context;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.sun.xml.internal.ws.api.policy.PolicyResolver.ServerContext;

public class IServlet extends HttpServlet{

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
//      取值
        String  str=Constant.str;
//      Object bao=Constant.obj;
        String bao=(String) Constant.map.get("bag");
//      输出到客户端
        resp.getWriter().print(str+"<br>");
        resp.getWriter().print(bao+"<br>");
        Constant.map.remove("car");
//      通过servletContext取值
//          获得servletContext对象
        ServletContext  sContext=getServletContext();
//      操作map
        String bag=(String) sContext.getAttribute("ck");
//      输出到客户端
        resp.getWriter().print(bag);
//      不喜欢就扔掉(删除)
        sContext.removeAttribute("ck");
        //遍历
        Enumeration<String> enumeration=sContext.getAttributeNames();
        while (enumeration.hasMoreElements()) {
            String key = (String) enumeration.nextElement();
            Object value=sContext.getAttribute(key);
            System.out.println(key+"====>"+value);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        super.doPost(req, resp);
    }

}
package my.servletlearn.context.resource;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class JServlet extends HttpServlet{

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
//      获得WEB-InF下的student.xml
        File file=new File("D:\\java\\workspace\\MyWeb\\WebContent\\WEB-INF\\student.xml");
//      以上获得student.xml的代码不正确
//      不正确,因为这样获得的tudent.xml指的是Eclipse工程下的文件,而我们真正要操作的是部署到tomcat下的资源
        File file2=new File("student.xml");
        System.out.println(file2.exists());
//      结论:file的相对路径行不通
//      解决方案:使用servletContext
        ServletContext sc=getServletContext();
//       "/"  ===>代表项目下
        InputStream iStream=sc.getResourceAsStream("/WEB-INF/student.xml");
        System.out.println(iStream);
//      获得资源的绝对路径
        String realPath=sc.getRealPath("/WEB-INF/student.xml");
        System.out.println(realPath);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        super.doPost(req, resp);
    }

}
package my.servletlearn.context.resource;

import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class KServlet extends HttpServlet{

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
/*//        获得资源的其他方式
//      使用class方法
//      "/"  ===>代表classes目录
        InputStream is2=this.getClass().getResourceAsStream("Student.xml");
        // "" ===> 不加 "/",代表当前文件所在目录
        InputStream is3=this.getClass().getResourceAsStream("student/xml");
        System.out.println(is2);
        System.out.println(is3);*/
        //---------------------------------------------------------------------------
        InputStream is4=this.getClass().getClassLoader().getResourceAsStream("");
//      区别就是不加"/" 还是相对于classes目录
        InputStream is5=this.getClass().getClassLoader().getResourceAsStream("/");
        System.out.println(is4);
        System.out.println(is5);
//      获得路径
        String path=this.getClass().getResource("student.xml").getPath();
        System.out.println(path+"path");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        super.doPost(req, resp);
    }

}

package my.servletlearn.demo;

import java.io.IOException;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class AServlet implements Servlet {
    @Override
    public void init(ServletConfig arg0) throws ServletException {
        // TODO Auto-generated method stub
//      init 是在第一次请求Aservlet时调用 ===>Servlet实例的创建是在第一次访问的时候
//      servlet在多次访问时,发现只调用了1次init方法,在多次访问,只创建了一个实例
        System.out.println("ASerlet的init方法被调用!");
    }
//  当客户端请求的时候调用service,参数1 request对象封装了请求信息,参数2 response 中填入信息生成的响应
    @Override
    public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
        // TODO Auto-generated method stub
        arg1.getWriter().print("hello world!");
        System.out.println("ASerlet的service方法被调用le!");
    }

    @Override
//  在服务器将要关闭时,会小会内存中的servlet实例,在真正小会之前会调用destroy方法
    public void destroy() {
        // TODO Auto-generated method stub
        System.out.println("ASerlet方法被调用了!");
    }

    @Override

    public ServletConfig getServletConfig() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
//  这个方法没有用
    public String getServletInfo() {
        // TODO Auto-generated method stub
        return null;
    }   


}
package my.servletlearn.generic;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public abstract class MyGenericServlet implements Servlet,ServletConfig{
    private ServletConfig config;
    @Override
    public void init(ServletConfig config) throws ServletException {
        // TODO Auto-generated method stub
        this.config=config;
    }
    @Override
    //不要忘记抽象方法不需要被实现
    public abstract void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException;

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

    @Override
    public ServletConfig getServletConfig() {
        // TODO Auto-generated method stub
        return config;
    }

    @Override
    public String getServletInfo() {
        // TODO Auto-generated method stub
        return null;
    }

    public String getInitParameter(String arg0) {
        return config.getInitParameter(arg0);
    }

    public Enumeration<String> getInitParameterNames() {
        return getServletConfig().getInitParameterNames();
    }

    public ServletContext getServletContext() {
        return getServletConfig().getServletContext();
    }

    public String getServletName() {
        return getServletConfig().getServletName();
    }

    /*public String getServletName() {
        return getServletConfig().getServletName();
    }
    public String getInitParameter(String args0) {
        return  getServletConfig().getInitParameter(args0);
    }

    public Enumeration getInitParameterNames() {
        return getServletConfig().getInitParameterNames();
    }

    public ServletContext getServletContext() {
        return getServletConfig().getServletContext();
    }*/


}
package my.servletlearn.generic;

import java.io.IOException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class CServlet extends MyGenericServlet{

    @Override
    public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
        // TODO Auto-generated method stub
//      String servletName=getServletConfig().getServletName();
        String servletName=getServletName();
//      String param=getInitParameter("name");
        arg1.getWriter().print(servletName);
    }

//  重新init方法
    public void init(ServletConfig config) throws ServletException {
        // TODO Auto-generated method stub
        System.out.println("C");
        super.init(config);
    }

}
package my.servletlearn.http;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import my.servletlearn.generic.MyGenericServlet;

public abstract class MyHttpServlet extends MyGenericServlet{
    public static final String Method_Get="GET";
    public static final String Method_Post="POST";
    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        // TODO Auto-generated method stub
//      优化:我们开发项目都是基于http协议的,而且服务器在service方法中传给ServletRequest
//      所以我们把request和response强转成HTTP的
        HttpServletRequest request=null;
        HttpServletResponse response=null;
        try {
            request=(HttpServletRequest) req;
            response=(HttpServletResponse) res;
            service(request, response);
        } catch (Exception e) {
            // TODO: handle exception
        }
    }
    public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
//      优化2:我想根据请求方式的不同,做不同的事情
//      获得客户端的请求方式
        String method=req.getMethod();//    Get/Post
//      根据请求方式的不同,调用不同的方法
        if (method.equals(Method_Get)) {
            doGet(res,req);
        }else if(method.equals(Method_Post)){
            doPost(res,req);
        }
    }
    public void doPost(HttpServletResponse res, HttpServletRequest req) {
        // TODO Auto-generated method stub

    }
    public void doGet(HttpServletResponse res, HttpServletRequest req) {
        // TODO Auto-generated method stub

    }

}
package my.servletlearn.http;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DServlet extends MyHttpServlet{

    @Override
    public void doPost(HttpServletResponse res, HttpServletRequest req) {
        // TODO Auto-generated method stub
        System.out.println("您现在使用的是POST访问方式");
    }

    @Override
    public void doGet(HttpServletResponse res, HttpServletRequest req) {
        // TODO Auto-generated method stub
        System.out.println("您现在使用的是GET访问方式");
    }

}
package my.servletlearn.thread;

import java.io.IOException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FServlet extends HttpServlet {
    private String name;
    private int i=0;

    public void init(ServletConfig config) throws ServletException {
        // TODO Auto-generated method stub
        System.out.println("F ");
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
//      name=req.getParameter("name");
        i++;
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        resp.getWriter().print("The number is:"+i);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        super.doPost(req, resp);
    }

}
package my.servletlearn2.demo;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class BServlet implements Servlet{
    private ServletConfig config;
    @Override
    public void init(ServletConfig config) throws ServletException {
        // TODO Auto-generated method stub
        this.config=config;
    }

    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        // TODO Auto-generated method stub
//      获得servlet的name
        String servletName=getServletConfig().getServletName();
//      将字符串输出到客户端(浏览器)
        res.getWriter().print(servletName+"<br>");
        /**
         * String getInitParameter(String name)
         * Enumeration getInitParameterNames()
         * webxml配置里面的init-param的信息
         */
        Enumeration<String> enumeration=getServletConfig().getInitParameterNames();
        while (enumeration.hasMoreElements()) {
            String key = (String) enumeration.nextElement();
            String value=getServletConfig().getInitParameter(key);
            res.getWriter().print(key+"===>"+value+"<br>");
        }
    }


    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

    @Override
    public ServletConfig getServletConfig() {
        // TODO Auto-generated method stub
        return config;
    }

    @Override
    public String getServletInfo() {
        // TODO Auto-generated method stub
        return null;
    }


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值