HTTP协议详解和Servlet开发入门

一、请求消息头
 Accept:浏览器可接受的MIME类型。(Tomcat的conf/web.xml)
 Accept-Charset:浏览器通过这个头告诉服务器,它支持哪种字符集
 Accept-Encoding::浏览器能够进行解码的数据编码方式
 Accept-Language:浏览器所希望的语言种类,当服务器能够提供一种以上的语言版本时要用到。 可以在浏览器中进行设置。
 *Referer:取值为一个URL。代表访问当前页面之前的页面地址。
 Content-Type:正文的MIME类型。text/html
 If-Modified-Since: Wed, 02 Feb 2011 12:04:56 GMT利用这个头与服务器的文件进行比对,如果一致,则从缓存中直接读取文件。
 User-Agent:浏览器类型
 Content-Length:表示请求消息正文的长度
 Connection:表示是否需要持久连接。如果服务器看到这里的值为“Keep -Alive”,或者看到请求使用的是HTTP 1.1(HTTP 1.1默认进行持久连接
 *Cookie:这是最重要的请求头信息之一 .向服务器传递cookie。会话技术有关
二、响应消息头
 *Location:结合302/307响应码,来实现请求重定向。用于指向新的地址
 *Content-Encoding:告知客户端服务器发送的数据使用的编码方式(GZIP)。
 *Content-Type: text/html; charset=GB2312服务器发送的内容的MIME类型
 *Refresh: 1;url=http://www.it315.org指示客户端刷新频率。单位是秒
   url:刷新到的新地址
 *Content-Disposition: attachment; filename=aaa.zip指示客户端下载文件
 *Set-Cookie:SS=Q0=5Lb_nQ; path=/search服务器端发送的Cookie。会话技术有关
 
 *Expires: -1  控制客户端不要缓存
 *Cache-Control: no-cache (1.1) 
 *Pragma: no-cache   (1.0)
三、Servlet创建及Servlet映射配置
1. Servlet创建的两种方式
    |--继承GenericServlet
 |--继承HttpServlet (推荐)
 
2. WEB应用中的web.xml文件进行如下配置:
 
   

<servlet>
      <!--Servlet's name-->
        <servlet-name>FirstServlet</servlet-name>
  <!--Servlet's path-->
        <servlet-class>com.itheima.FirstServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>FirstServlet</servlet-name>
  <!--virtual path-->
        <url-pattern>/abc</url-pattern>
    </servlet-mapping>



四、Servlet映射配置中使用通配符*
   方式一:*.扩展名 eg: *.do
   方式二; /action/*
五、默认的Servlet
    如果请求的某个WEB应用的URL地址,在web.xml文件中没有对应的servlet映射,这样的请求就会交给缺省的servlet进行处理(在/conf/web.xml已经配置,如下)
  
    

<servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>   
     <!-- The mapping for the default servlet -->
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>


六、Servlet的生命周期
1.servlet生命周期
Servlet具有良好的生命周期的定义,包括加载和实例化,初始化,处理请求以及服务结束。这个生命周期由javax.servlet.Servlet接口的 init,service和destory方法完成

当客户第一次访问服务器上的某个动态资源时,服务器为其创建对应servlet的实例对象(servlet实例化),容器运行其init方法,完成对servlet的初始化.然后通过调用service()方法实现,根据不同的请求调用doGet或者doPost方法.当服务结束后,web容器调用servlet的destroy方法,将其销毁.

destroy方法也只执行一次

2.<load-on-startup>元素的配置
web.xml中配置如下:
<servlet>
  <servlet-name>invoker</servlet-name>
  <servlet-class>
   org.apache.catalina.servlets.InvokerServlet
  </servlet-class>
  <!-指示当容器启动时第一个被实例化的Servlet 值应该是一个0或者大于0的正整数. 数字越小,优先级越高->
  <load-on-startup>2</load-on-startup>
 </servlet>
若<servlet>元素中定义了该元素,那么该WEB应用在启动时就会自动装载servlet并创建其对象,而且会调用该servlet对象的init方法

具体用途;
可以为WEB应用创建一个initServlet,把这个servlet配置为应用启动时装载,为整个web应用创建必要的数据库表和数据

Servlet的线程安全问题

private int sum = 0;
public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  sum++;
  try {
   Thread.sleep(5000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  response.getWriter().write(sum+"");
 }


 当多个用户访问该servlet时,会出现线程安全问题
 解决方案
 1.使用Java同步机制对多线程同步:运行效率低   
    2.使用SingleThreadModel接口   该接口是一个标记接口(接口内无内容) 实现创建了多个servlet对象进行服务(类似于线程池),作用有限并不能解决大数量的同时访问.该接口已Deprecated
    3.合理决定在Servlet中定义的变量的作用域


七、ServletConfig对象 
 作用:获取针对某个Servlet配置的参数

<servlet>
    <servlet-name>ServletDemo44</servlet-name>
    <servlet-class>com.itheima.ServletDemo4</servlet-class>
    <init-param>
     <param-name>encoding</param-name>
     <param-value>UTF-8</param-value>
    </init-param>
</servlet>
eg:
1、getInitParameter(String paramName):获取指定参数的取值
         String pValue = config.getInitParameter("encoding");
2、getInitParameterNames() :获取该Servlet所有的参数名称 
        Enumeration<String> params =  config.getInitParameterNames();
  while(params.hasMoreElements()){
   String name = params.nextElement();
   String value = config.getInitParameter(name);
   System.out.println(name+":::::"+value);
   }



3、getServletName() :获取Servlet在web.xml中注册的名称:
eg: <servlet-name>ServletDemo44</servlet-name>中的ServletDemo44
八、ServletContext对象

1、代表整个JavaWeb应用。每个JavaWeb应用都有自己唯一的ServletContext对象
2、在容器启动时就会为每个JavaWeb应用产生一个ServletContext对象
3、ServletContext对象还是一个域对象(理解为其内部维护了一个大Map<String,Object>)
 a、getAttribute(String name):获取Map中的某个对象
 b、setAttribute(String name,Object obj):向Map中添加一个对象
 c、removeAttribute(String name):从Map中删除某个对象

使用场景:数据共享(整个Web应用的数据共享)

九、重定向与转发
转发与重定向的区别;
简单地讲:转发是一次请求,重定向是两次请求
具体地来说,前者仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址;后者则是完全的跳转,浏览器将会得到跳转的地址,并重新发送请求链接。这样,从浏览器的地址栏中可以看到跳转后的链接地址。所以,前者更加高效,在前者可以满足需要时,尽量使用forward()方法,并且,这样也有助于隐藏实际的链接。在有些情况下,比如,需要跳转到一个其它服务器上的资源,则必须使用sendRedirect()方法。
转发
eg:
     ServletContext sc = getServletContext();
  //得到转发器
  RequestDispatcher rd = sc.getRequestDispatcher("/Demo1");
  rd.forward(request, response);
eg:重定向
response.sendRedirect("/day04_web/a.html");  

十、加载配置文件
1、ServletContext的getRealpath(String path):参数path必须以"/"开头,代表当前JavaWeb应用的根目录。
可以加载任何位置上的配置文件

eg:

private void test1() throws FileNotFoundException, IOException {
        //WEB-INF目录下
  String path = getServletContext().getRealPath("/WEB-INF/db.properties");
        // src根目录下
  // String path = getServletContext().getRealPath("/WEB-INF/classes/db.properties");

  // 具体的包中
  //String path = getServletContext().getRealPath("/WEB-INF/classes/com/itheima/db.properties");
  InputStream in = new FileInputStream(path);

  Properties p = new Properties();
  p.load(in);
  System.out.println("读取WEB-INF目录下的配置文件.......");
  System.out.println(p.getProperty("username"));
  System.out.println(p.getProperty("password"));
 }


 


2、利用类加载器:
类加载器只能加载classes目录下的配置文件,不适合加载特别大的配置文件。
如果配置文件在classes根目录下。加载路径:cfg.properties
如果配置文件在classes中的某个包中。加载路径:com/itheima/cfg.properties

eg:

private void test2() throws FileNotFoundException, IOException {
  ClassLoader c = ServletDemo7.class.getClassLoader();
  // //src根目录下
  // InputStream in = c.getResourceAsStream("db.properties");
  // 具体的包中
  InputStream in = c.getResourceAsStream("com/itheima/db.properties");
  Properties p = new Properties();
  p.load(in);
  System.out.println("利用类加载器读取配置文件");
  System.out.println(p.getProperty("username"));
  System.out.println(p.getProperty("password"));
 }



3、利用ResourceBundle进行加载(国际化时的一个类)
如果配置文件在classes根目录下。加载路径:cfg(基名,不带扩展名的名)
如果配置文件在classes中的某个包中。加载路径:com.itheima.cfg  

private void test3() throws FileNotFoundException, IOException {
  // src根目录下
  // ResourceBundle rb = ResourceBundle.getBundle("db");//必须是基名(不带扩展名)
  // 具体包中
  ResourceBundle rb = ResourceBundle.getBundle("com.itheima.db");//必须是基名(不带扩展名)
  System.out.println(rb.getString("username"));
  System.out.println(rb.getString("password"));

 }


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值