一、请求消息头
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")); }