学习笔记_Servlet

一、什么是servlet? 能做什么?

sun公司制订的一种用于扩展web服务器功能的组件规范。

  • 扩展:
    web服务器本身没有计算能力,也就是说,不能处理动态资源的请求。servlet可以处理动态资源的请求。

  • 组件:
    组件是符合规范,完成一定功能,并可以单独部署的软件模块。组件一般不能独立运行,需要依赖容器才能运行。  

  • 容器:
    在是一种程序,提供组件的运行环境,并且管理组件的生命周期。

  • servlet容器:

    提供servlet运行的环境,并且管理servlet的生命周期。一般常见的web服务器,比如tomcat, 除了是一个servlet容器以外,同时,也是一个web服务器,就是说已经集成了Servlet容器。

  • 能做什么?

    servlet只能够采用java语言来开发,servlet可以做java类能做的所有的事情。

二、如何开发一个servlet?

step1 写一个java类,实现Servlet接口或者继承HttpServlet类。

step2 编译 (依赖servlet api–[servlet-api.jar])
   javac -cp servlet-api.jar -d . HelloWorld.java

step3 打包(定义一个特定的目录结构,将相应的字节码,配置文件,相关的jar文件放到对应的
   录结构里) 
 

appname(名称任意,一般称为应用名)
WEB-INF(必须这样写)
    classes(放.class文件)
    lib(可选,放.jar文件)
    web.xml(部署描述文件)
    html/jsp  

step4 部署(将step3中的结果放到服务器特定的目录,对于tomcat,是webapps)

step5 启动服务器

JAVA_HOME:c:\jdk1.6
path:%JAVA_HOME%\bin
classpath:.;c:\jdk1.6\lib

startup.bat
系统变量中:JAVA_HOME:jdk的路径
startup.sh
启动成功:http://localhost:8080
关闭服务器
shutdown.bat
shutdown.sh  

step6 访问servlet
http://localhost:8080/appname/url-pattern

三、servlet是如何运行的?

假如在浏览器地址栏输入了如下地址:
http://ip:port/helloworld/hello
这里写图片描述
1)浏览器依据ip,port连接服务器。

2)浏览器将请求数据按http协议打成一个http请求数据包(包含了 helloworld/hello)

3)服务器当中的一个负责通讯的模块(一般称为servlet引擎)会创建HttpServletRequest的一个实例(HttpServletRequest实际上是一个接口,由服务器提供者来实现),该实例包含了请求数据包中的数据。另外,还创建了一个HttpServletResponse的一个实例,包含了响应数据包中的数据

4)服务器依据helloworld/hello找到web.xml,依据web.xml中的信息找到对应的Servlet类名。会查看该Servlet有没有对应的实例,如果没有,则创建实例,有的话,就不创建,使用现成的实例。接下来,调用service()方法。service方法里面的代码可以通过HttpServletRequest提供的方法来获得请求中的数据,并且,也可以将处理之后的结果通过HttpServletResponse提供的方法设置返回的结果。

5)Servlet引擎从HttpServletResponse获取数据,生成http响应数据包,发送给浏览器。

四、Servlet生命周期方法

以下方法都是由Servlet容器负责调用:

1>构造器:只被调用一次,只有第一次请求Servlet时,创建Servlet的实例,调用构造器
这说明Servlet是单实例的!

2>init 方法:只被调用一次,在创建好实例后立即被调用,用于初始化Servlet

如果想定义自己的初始化过程,可以override init()方法。
方式一: override init(ServletConfig config);
方式二: override init()
一般最好使用方式二

3>service:被多次调用。每次请求都会调用service方法。实际用于响应请求的。

4>destroy:只被调用一次。在当前Servlet所在的WEB应用被卸载前调用。用于释放当前Servlet所占用资源,将Servlet引用的对象置为空。

五、load-on-startup参数:

1>配置在Servlet节点中

<servlet>
    <!--Servlet 注册的名字-->
    <servlet-name>helloServlet</servlet-name>
    <!--Servlet 的全类名-->
    <servlet-class>com.javaweb.HelloServlet</servlet-class>
    <load-on-startup>2</load-on-startup>
</servlet>

2>load-on-startup:可以在指定Servlet被创建的时机。
  若为负数,则在第一次请求时被创建,
  若为0或正数,则在当前Web应用Servlet容器加载时创建实例,且数值越小越早被创建。

六、ServletConfig

ServletConfig:封装了Servlet的配置信息,并且可以获取ServletContext对象

1>配置Servlet初始化参数

  <servlet>
    <!--Servlet 注册的名字-->
    <servlet-name>helloServlet</servlet-name>
    <!--Servlet 的全类名-->
    <servlet-class>com.javaweb.HelloServlet</servlet-class>

    <!--配置Servlet初始化参数-->
    <init-param>
        <param-name>user</param-name>
        <param-value>root</param-value>
    <init-param>

    <init-param>
        <param-name>password</param-name>
        <param-value>1230</param-value>
    <init-param>
    <!--注意!!!  必须将初始化参数放在前面-->
    <load-on-startup>2</load-on-startup>
    </servlet>

2>获取初始化参数:

-getInitParameter(String name):获取指定参数名的初始化参数
-getInitParameterNames():获取【参数名】组成的Enumeration
    public void init(ServletConfig servletConfig)thows ServletException{
         String user = servletConfig.getInitParameter("user");
         System.out.println("user:  "+user);

         Enumeration<String> names = serveltConfig.getInitParameterNames();
         while(names.hasMoreElements()){
           String name = names.nextElement();
          String value = servletConfig.getInitParameter(name);
            System.out.println("--"+ name +":  "+ value);
         }
     }

七、ServletContext

1>可以由ServletConfig获取

ServletContext servletContext = servletConfig.getServletContext();

2>该对象代表当前WEB应用:可以认为ServletContext是当前WEB应用的一个大管家,可以从中获取当前WEB应用的各方面信息。
①获取当前WEB应用的初始化参数【可以被所有的Servlet所获取,而Servlet的初始化参数只可以被自己所使用】

    <context-param>
        <param-name>driver</param-name>
        <param-value>cn.edu.computer.HellowServlet</param-value>
    </context-param>

    <context-param>
        <param-name>jdbcUr1</param-name>
        <param-value>
            jdbc:mysql://127.0.0.1:3306/java
        </param-value>
    </context-param>
       方法:
      ServletContext.getInitParameter();
      ServletContext.getInitParameterNames();

②获取当前WEB应用的某一个文件在服务器上的绝对路径,而【不是部署前】的
getRealPath()
③获取当前WEB应用的名称:
getContextPath()
代码:

String contextPath = servletContext.getContextPath();
System.out.println(contextPath);

④获取当前WEB应用的某一个文件对应的输入流:
getResourceAsStream(String path)-path的/为当前WEB应用的根目录
代码:

ClassLoader classLoader = getClass().getClassLoader();
InputStream is = classLoader.getResourceAsStream("jdbc.properties");
System.out.println("1 "+is );


InputStream is1 = servletContext.getResourceAsStream("WEB-INF/classes/jdbc.properties");
System.out.println("2 "+is1);

⑤和attribute相关的几个方法

八、如何在Servlet中获取请求信息:

1>Servlet的service()方法用于应答请求。每次请求都会调用该方法。

public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException {
ServletRequest:封装了请求信息,可以从中获取到任何请求信息
ServletResponse:封装了响应信息,如果想给用户什么响应,具体可以使用该接口方法实现

这两个接口的实现类都是服务器给予实现的,并在服务器调用service()方法时代入

2>ServletRequest

①获取请求参数
String getParameter(String name):根据请求参数名字,返回参数值。
若请求参数有多个值(例如:checkbox)该方法只能获取到第一个提交的值,这时 需使用getParameterValues():

String[] getParameterValues(String name):根据请求参数名字,返回请求参数返回对应参数数组

Enumeration getParameterNames():返回参数名对应的Enumeration对象
类似于ServletConfig(或ServletContext())的getInitParameterNames()方法

Map getParameterMap():返回请求参数的键值对-key:参数名,value:参数值,String数组类型

②获取请求的URL:
HttpServletRequest httpServletRequest = (HttpServletRequest)request;
String requestURI = httpServletRequest.getRequestURI();
URI:/day29/loginServlet

③获取请求方式:
String method = httpServletRequest.getMethod(); //GET

④若是GET请求,获取请求参数对应的那个字符串,即?后面的字符串
String queryString = httpServletRequest.getQueryString(); //user=dd&password=123456&interesting=game…

⑤获取请求的Servlet的映射路径
String servletPath = httpServletRequest.getServletPath();
// /loginServlet

⑥和attribute相关的几个方法

3>HttpServletRequest:是ServletRequest的子接口。针对于HTTP请求所定义,里面包含了大量获取HTTP请求相关的方法。

4>ServletResponse:封装了响应信息,如果想给用户什么响应,具体可以使用该接口的方法实现。

①getWriter():返回PrintWriter对象。调用该对象的print()方法,将把print()中的参数直接打印到浏览器。

②设置相应的内容类型:response.setContentType(“application/msword”); //将在响应以Word文件方式发送

③void sendRedirect(String location): 请求的重定向。(此方法为HttpServletRespnse中定义)

九、GenericServlet:

1>是一个Servlet.是Servlet接口和ServletConfig接口的实现类,是一个【抽象类】。其中的service方法为抽象方法。

2>如果新建的Servlet程序直接继承GenericSerlvet会使开发更简洁。

3>具体实现:

①在GenericServlet中声明了一个ServletConfig类型的成员变量,在init(ServletConfig)方法中对其进行了初始化

②利用servletConfig成员变量的方法实现了ServletConfig接口的方法

③还定义了一个init()方法,在init(ServletConfig)方法中对其进行调用,子类可以直接覆盖init()在其中实现对Servlet的初始化

④不建议直接覆盖init(ServletConfig),因为如果忘记编写super.init(ServletConfig),而还使用了ServletConfig接口的方法,则
会出现空指针异常。

⑤新建的init(){}并非Servlet的生命周期方法,而init(ServletConfig name)是。
public abstract class MyGenericServlet implements Servlet,ServletConfig{}

十、HttpServlet:

1>是一个Servlet,继承自GenericServlet,针对HTTP协议所定制。

2>在service()方法中直接把ServletRequest和ServletResponse转化为HttpServletRequest和HttpServletResponse并调用了重载的service(HttpServletRequest,HttpServletResponse)

在service(HttpServletRequest,HttpServletResponse)获取请求方式:request.getMethod()
根据请求方式又创建了doXxx() 方法(如:doGet()和 doPost()

3>实际开发中,直接继承HttpServlet,并且根据请求方式复写doXxx()方法接口

4>优点:直接针对性的覆盖doXxx()方法;
     直接使用HttpServletRequest 和 HttpServletResponse,就不再需要强制转换。

public class MyHttpServlet extends MyGenericServlet {

    @Override
    public void service(ServletRequest req, ServletResponse res)
            throws ServletException, IOException {
        if (req instanceof HttpServletRequest) {
            HttpServletRequest request = (HttpServletRequest) req;

            if (res instanceof HttpServletResponse) {
                HttpServletResponse response = (HttpServletResponse) res;
                service(request, response);
            }
        }

    }

    public void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException{
        String method = request.getMethod();
        if("GET".equalsIgnoreCase(method)){
            doGet(request,response); 
        }else if("POST".equalsIgnoreCase(method)){
            doPost(request, response);
        }
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException{

    }

    public void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException{

    }
}

最后附上核心类与接口联系图:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值