标签:
我也苦恼自己的博客书写格式很烂,标题+代码格式。因为每天课程量比较大,没时间花在书写格式上面,如看不习惯请多多见谅。我坚持每天书写博客主要是养成一个习惯,并一直延续下去,虽然内容很空泛,目的也算达到了,总之为了巩固知识点,坚持不懈
什么是servlet 它其实就是java类,运行在服务器端,主要用途就是处理用户发送HTTP请求,并且作出响应 学习两个包:javax.servlet/javax.servlet.http Servlet容器就是Tomcat,也就是Web服务器
myapp |--WEB-INF: |--classes(Servlet编译之后代码放到这个包下) |--lib |--web.xml |--css |--html |--img |--js 1.手动建立Servlet类 package com.itheima.servlet; import javax.servlet.*; import java.io.*; public class HelloWorldServlet extends GenericServlet { public void service(ServletRequest req,ServletResponse res)throws ServletException,IOException { res.getWriter().write("Hello World"); } } 2.编译 set classpath=%classapth%;C:\apache-tomcat-6.0.37\lib\servlet-api.jar javac -d . HelloWorldServlet.java 3.配置文件 在web.xml中添加servlet的配置 <servlet> <!--自己配的一个名称--> <servlet-name>hello</servlet-name> <!--一定是servlet类所对应全路径--> <servlet-class>com.itheima.servlet.HelloWorldServlet</servlet-class> </servlet> <servlet-mapping> <!--自己配的一个名称--> <servlet-name>hello</servlet-name> <!--映射的一个URL,一定是/开头(具体路径)--> <url-pattern>/cgx/aj</url-pattern> //配置Mapping URL路径名前面一定要加斜杠/,斜杠代表当前应用目录 </servlet-mapping>
注意:若项目名修改了,对应的这个project facet路径也要修改一致 (右键Properties-->MyEclipse-->[Project Facets]-->Web-->Context Root) 替换servlet模版 *wizard*.jar-->template/Servlet.java(模板文件)
当用户发起请求起, 始终调用的是的是service()方法,而这个方法内部会进行判断 并决定是调用doGet(),还是doPost() 而咱们自己定义的Servlet又重写了doGet(),doPost() 结论: 不要自己重写service()方法,因为父类有这个方法,一般重写doGet/doPost方法 扩展:采用了模版方法设计模式 public class A { service() { doGet(); doPost(); } public abstract void doGet(); public abstract void doPost(); } public class B extends A { public void doGet() { ... } public void doPost() { ... } } @Test public void test() { A a = new B(); a.service(); }
当用户第一次访问的时候实例化/初始化/提供服务 第二次访问只提供对外服务 1. 在默认情况下,Servlet生命周期执行过程如下: 在用户第一次请求时: 1.实例化:构造方法1次 2.初始化:(init):1次 3.服务:(service),以后每次请求,都会直接执行service() :N次 4.销毁:当服务器停止或应用被移除,此时销毁destory()方法执行: 1次 2. 改写生命周期 是通过<load-on-startup>来实现的 取值: 整数(1开始 越小优先级越高) 改写之后 服务器启动时,对应的Servlet就会执行生命周期(实例化,初始化)以后每次用户执行时,走service()方法 优点:当用户每一次请求时,速度会变快 缺 点:如果load-on-startup配置太多,Tomcat启动速度会变慢
1.可以配多个映射地址 <servlet-mapping> <servlet-name>myfirst</servlet-name> <url-pattern>/servlet/MyFirstServletDemo1</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>myfirst</servlet-name> <url-pattern>/aj</url-pattern> </servlet-mapping> 2.映射还可以使用通配符* 使用方式: a、*.扩展名:必须以*开头,以某个扩展名结尾。比如*.do b、/action/*:必须以/开头,*在末尾。比如/action/* 原则:b优先级比a高。如果都是a或都是b,从前往后匹配。 完全匹配的映射优先级最高 不要这写成/*.action 3.总结规律: 1.能精确匹配的用精确匹配 2./*优先级高于*.扩展名 还可以配置一个缺省的Servlet 1.写法: / <servlet-mapping> <servlet-name>myfirst</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> 2.当请求静态资源时,如果找不到,则执行缺省的Servlet if("1.jpg"找到了){ 显示图片 }else{ 没有找到 显示404 } 3.这个缺省的Servlet一般不配置,为什么? 因为在Tomcat的web.xml中有
说明servlet不是线程安全的,而且它设计目标就是采用多线程来处理用户请求 线程安全问题解决方法: 1.synchronized:线程同步 2.用单线程:就是实现SingleThreadModel接口 总结:这两种方法都不行,违背了设计意图!!! 最终解决办法: 程序员自己注意,不要定义成员变量,尽量用局部变量 合理决定在Servlet中定义的变量的作用域
<servlet><!--对ServletDemo3这个Servlet进行配置--> <servlet-name>ServletDemo3</servlet-name> <servlet-class>com.itheima.servlet.ServletDemo3</servlet-class> <init-param> <!--表示aaa的值是bbb --> <param-name>aaa</param-name> <param-value>bbb</param-value> </init-param> </servlet> //获取 Servlet 的配置信息,并打印 public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { ServletConfig sc = getServletConfig(); String value = sc.getInitParameter( "encoding" ); if (value== null ) value = "GBK" ; response.getWriter().write(value); //在控制台打印该 Servlet 所有的参数及取值 Enumeration e = sc.getInitParameterNames(); //所有参数名 while (e.hasMoreElements()){ String paramName = (String)e.nextElement(); System. out .println(paramName+ "=" +sc.getInitParameter(paramName)); } }
它是服务器产生的一个对象,它用于实现各个Servlet之间信息共享,用于获取全局初始化参数 1). 它是运行在web容器中,每个web应用程序都会有一个自己唯一的ServletContext对象 2). 由web容器加载应用时,就创建好了 3). 它跟web应用程序同生命周期,随着web应用启动而存在,随着应用的卸载而消失 作用: 1). 作为一个全局的域对象来用(四大域作用范围最广),可以实现应用范围的数据共享,用于获取全局初始化参数 实现原理: 就是在全局范围内维护一个Map集合 setAttribute(key,Value) Object obj = getAttribute(key); removeAttribute(key); 2). 获取全局初始化参数 getInitParameter("") getInitParameterNames();
1. 什么是转发? A-->B--C 重定向 A----B(没有资源) A----C 实现步骤: 1.得到转发器 路径一定是绝对路径 RequestDispatcher rd = getServletContext().getRequestDispatcher("/servlet/ServletContextDemo1"); 2.转发 rd.forward(request, response); 2.实现方式 //放入iphone6 sc.setAttribute("gift", "iphone6"); //转发,采用ServletContext实现转发时,不能用相对路径,只能用/开头代表一个绝对路径 RequestDispatcher rd = sc.getRequestDispatcher("/servlet/ServletContextDemo5");//转发器 //rd.forward(request, response);//转发 //在实现包含时,它会将目标对象的响应正文包含进来,如果设置有响应头也不起作用 rd.include(request, response);//包含
转发的特点: 1). 地址栏不变 2). 说明客户端向服务器发送只有一次请求 3). 放在reques域中的值可以共享 重定向 1). 地址栏改变 2). 客户端发送了2次请求 3). 放在request 域中的数据不能共享
//1. 根据所学的由相对路径得到绝对路径getRealPath,只适合web项目 //String absolutePath = getServletContext().getRealPath("/WEB-INF/classes/cfg2.properties"); //String absolutePath = getServletContext().getRealPath("/WEB-INF/classes/com/itheima/day07Servlet/cfg2.properties"); String absolutePath = getServletContext().getRealPath("/WEB-INF/cfg3.properties"); Properties prop = new Properties(); //得到一个Properties对象 prop.load(new FileInputStream(absolutePath)); //加载这个文件到内存 response.getOutputStream().write(prop.getProperty("p").getBytes()); //2. ResourceBundle 资源文件加载器 //适用范围: Web项目,java项目都可以,只能加载src下资源 //ResourceBundle rb = ResourceBundle.getBundle("cfg2"); //基名:就是不带扩展名 ResourceBundle rb = ResourceBundle.getBundle("com.itheima.day07Servlet.cfg"); //基名:就是不带扩展名 String value = rb.getString("p"); response.getOutputStream().write(value.getBytes()); 3. 类加载器ClassLoader ClassLoader cl = this.getClass().getClassLoader(); //InputStream is = cl.getResourceAsStream("cfg2.properties"); InputStream is = cl.getResourceAsStream("com/itheima/day07Servlet/cfg.properties"); //InputStream is = cl.getResourceAsStream("../cfg3.properties"); //WEB-INF下 Properties prop = new Properties(); prop.load(is); response.getOutputStream().write(prop.getProperty("p").getBytes());
标签:
原文地址:http://www.cnblogs.com/codingpark/p/4231112.html