简介
我也苦恼自己的博客书写格式很烂,标题+代码格式。因为每天课程量比较大,没时间花在书写格式上面,如看不习惯请多多见谅。我坚持每天书写博客主要是养成一个习惯,并一直延续下去,虽然内容很空泛,目的也算达到了,总之为了巩固知识点,坚持不懈
Servlet快速入门
0. Servlet简介
什么是servlet 它其实就是java类,运行在服务器端,主要用途就是处理用户发送HTTP请求,并且作出响应学习两个包:javax.servlet/javax.servlet.httpServlet容器就是Tomcat,也就是Web服务器
1. 手工部署web应用
myapp |--WEB-INF: |--classes(Servlet编译之后代码放到这个包下) |--lib |--web.xml |--css |--html |--img |--js1.手动建立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.java3.配置文件 在web.xml中添加servlet的配置hello com.itheima.servlet.HelloWorldServlet hello /cgx/aj //配置Mapping URL路径名前面一定要加斜杠/,斜杠代表当前应用目录
2. MyEclipse项目注意事项
注意:若项目名修改了,对应的这个project facet路径也要修改一致 (右键Properties-->MyEclipse-->[Project Facets]-->Web-->Context Root)替换servlet模版 *wizard*.jar-->template/Servlet.java(模板文件)
3. doGet/doPost分析
当用户发起请求起, 始终调用的是的是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() { ... }}@Testpublic void test() { A a = new B(); a.service();}
4. Servlet生命周期
当用户第一次访问的时候实例化/初始化/提供服务第二次访问只提供对外服务1. 在默认情况下,Servlet生命周期执行过程如下: 在用户第一次请求时: 1.实例化:构造方法1次 2.初始化:(init):1次 3.服务:(service),以后每次请求,都会直接执行service() :N次 4.销毁:当服务器停止或应用被移除,此时销毁destory()方法执行: 1次 2. 改写生命周期 是通过来实现的 取值: 整数(1开始 越小优先级越高) 改写之后 服务器启动时,对应的Servlet就会执行生命周期(实例化,初始化)以后每次用户执行时,走service()方法 优点:当用户每一次请求时,速度会变快 缺 点:如果load-on-startup配置太多,Tomcat启动速度会变慢
5. web.xml中Servlet具体详细配置
1.可以配多个映射地址myfirst /servlet/MyFirstServletDemo1 2.映射还可以使用通配符* 使用方式: a、*.扩展名:必须以*开头,以某个扩展名结尾。比如*.do b、/action/*:必须以/开头,*在末尾。比如/action/* 原则:b优先级比a高。如果都是a或都是b,从前往后匹配。 完全匹配的映射优先级最高 不要这写成/*.action3.总结规律: 1.能精确匹配的用精确匹配 2./*优先级高于*.扩展名 还可以配置一个缺省的Servlet 1.写法: / myfirst /aj 2.当请求静态资源时,如果找不到,则执行缺省的Servlet if("1.jpg"找到了){ 显示图片 }else{ 没有找到 显示404 } 3.这个缺省的Servlet一般不配置,为什么? 因为在Tomcat的web.xml中有 myfirst /
6. 线程安全
说明servlet不是线程安全的,而且它设计目标就是采用多线程来处理用户请求线程安全问题解决方法: 1.synchronized:线程同步 2.用单线程:就是实现SingleThreadModel接口 总结:这两种方法都不行,违背了设计意图!!! 最终解决办法: 程序员自己注意,不要定义成员变量,尽量用局部变量 合理决定在Servlet中定义的变量的作用域
Servlet之ServletConfig入门
针对某个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)); } } ServletDemo3 com.itheima.servlet.ServletDemo3 aaa bbb
Servlet之ServletContext入门
1. 什么是ServletContext及作用
它是服务器产生的一个对象,它用于实现各个Servlet之间信息共享,用于获取全局初始化参数1). 它是运行在web容器中,每个web应用程序都会有一个自己唯一的ServletContext对象2). 由web容器加载应用时,就创建好了3). 它跟web应用程序同生命周期,随着web应用启动而存在,随着应用的卸载而消失作用: 1). 作为一个全局的域对象来用(四大域作用范围最广),可以实现应用范围的数据共享,用于获取全局初始化参数 实现原理: 就是在全局范围内维护一个Map集合 setAttribute(key,Value) Object obj = getAttribute(key); removeAttribute(key);2). 获取全局初始化参数 getInitParameter("") getInitParameterNames();
2. 实现Servlet的转发
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);//包含
3. 转发与重定向区别
转发的特点: 1). 地址栏不变 2). 说明客户端向服务器发送只有一次请求 3). 放在reques域中的值可以共享重定向 1). 地址栏改变 2). 客户端发送了2次请求 3). 放在request 域中的数据不能共享
4. 读取资源文件3种方式
//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. 类加载器ClassLoaderClassLoader 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());