----------------------------------------------------------------------------------------------
[版权申明:本文系做者原创,转载请注明出处]
文章出处:http://blog.csdn.net/sdksdk0/article/details/51953305
做者:朱培 ID:sdksdk0 邮箱: zhupei@tianfang1314.cn html
--------------------------------------------------------------------------------------------java
本文主要介绍servlet的基本使用操做,是一些很是基础的知识,主要掌握servlet做用域、servlet映射、请求转发、ServletConfig配置、ServletContext等的使用,最后以一个简易的文件下载的案例来讲明Servlet的应用。git
Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet能够响应任何类型的请求,但绝大多数状况下Servlet只用来扩展基于HTTP协议的Web服务器。
最先支持Servlet标准的是JavaSoft的Java Web Server,此后,一些其它的基于Java的Web服务器开始支持标准的Servlet。servlet是运行在web服务器中的小型java程序,经过HTTP接收和响应web客户端的请求。github
Servlet 看起来像是一般的 Java 程序。Servlet 导入特定的属于 Java Servlet API 的包。由于是对象字节码,可动态地从网络加载,能够说 Servlet 对 Server 就如同 Applet对 Client 同样,可是,因为 Servlet 运行于 Server 中,它们并不须要一个图形用户界面。从这个角度讲,Servlet 也被称为 FacelessObject。web
一、编码一个类,实现javax.servlet.Servlet接口或者继承javax.servlet.GenericServlet浏览器
public class HelloServlet extends GenericServlet{ public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException{ res.getOutputStream().write("hello world".getBytes()); } }
二、配置一个servlet。web.xml中tomcat
<!--声明一个servlet --> <servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>cn.tf.servlet.HelloServlet</servlet-class> </servlet> <!-- 给servlet映射一个url地址 --> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
三、把应用部署到Tomcat中,以后才能够看到效果。安全
六、找到对应的类HelloServlet.class:先从应用的class目录、应用的lib中的jar包、Tomcat\lib目录中全部的jar包这个顺序进行查找。 实例化servlet对象,接着调用init方法、第一次访问时调用.服务器
七、有Tomcat调用该类的servlet方法网络
实例化对象,第一次访问时调用.
init() 一旦初始化完成,该实例就一直保持在Tomcat的内存中,第一次访问时调用.。
getServletInfo() 返回做者、版权等信息。
service() 用户每次请求都会执行。
destroy() 关闭tomcat的时候调用。
加载和实例化 Servlet。这项操做通常是动态执行的。然而,Server 一般会提供一个管理的选项,用于在 Server 启动时强制装载和初始化特定的 Servlet。
public class ServletDemo2 implements Servlet { public ServletDemo2(){ System.out.println("调用了servletDemo2的构造方法"); } //初始化 @Override public void init(ServletConfig arg0) throws ServletException { System.out.println("调用了init方法"); } //获取servlet配置的方法 @Override public ServletConfig getServletConfig() { return null; } //返回做者,版权等信息 @Override public String getServletInfo() { return null; } //服务器方法 @Override public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException { System.out.println("执行了service方法"); } //销毁方法 @Override public void destroy() { System.out.println("服务器被销毁"); } }
经过web.xml让servlet在Tomcat加载应用时,就完成实例化和初始化。
<load-on-startup>2</load-on-startup>
GenericServlet和HttpServlet的对比
从大到小:servlet、GenericServlet、HttpServlet myeclipse默认的是继承HttpServlet。这个时候不须要覆盖service方法。继承了doGet、doPost方法。
映射地址:多个不一样的地址能够映射到同一个servlet.
通配符映射:*匹配全部字符串 url-pattern:
匹配原则: 绝对匹配: /开头的批评 扩展名结尾的 (优先级高->低).
默认的servlet:一个servlet的url-pattern为一个/,那么这个servlet就是默认的servlet。
线程安全
对于单例对象:多线程就可能出现线程安全问题。 实现SingleThreadModel接口后,控制线程安全问题彻底由服务器来决定。
在servlet中尽可能不要使用实例变量,应该要使用局部变量。
将编码配置放到web.xml中。
<init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param>
读取配置参数的值: ServletConfig
String value=getServletConfig().getInitParameter("encoding");
一、 servletContext的实例就表明当前的javaweb应用。 一个javaweb只有一个servletContext的实例。当前应用中的其余资源(servlet、jsp、html等)共享同一个ServletContext.
二、生命周期 应用被服务器加载时产生ServletContext实例。 生命周期是 从servletContext建立到服务器关闭
三、得到ServletContext的引用
ServletContext sc=getServletContext();
sc.setAttribute("a", "demo1"); Object value=sc.getAttribute("a");
四、得到web应用的全局参数 在web.xml中配置
<context-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </context-param>
调用:
ServletContext sc=config.getServletContext(); sc.getInitParameter("encoding");
五、servlet请求转发 从demo4转到demo3
ServletContext sc=getServletContext(); RequestDispatcher dispatcher=sc.getRequestDispatcher("/servlet/Demo3"); dispatcher.forward(request, response);
六、读取配置文件
ResourceBundle只适合读取properties文件,只能读取类路径中的配置文件,WEB-INF/class或者jar中的文件:
ResourceBundle rb=ResourceBundle.getBundle("cn.tf.servletContext.c");
ServletContext:String getRealPath(String path), 获取到文件的真实路径,只适合javaweb应用,可以读取其任何位置的任意文件:
ServletContext sc=getServletContext(); String path=sc.getRealPath("/WEB-INF/a.properties"); System.out.println(path); Properties prop=new Properties(); prop.load(new FileInputStream(path)); System.out.println(prop.getProperty("key"));
用类加载器:文件位置要在在类路径中,能够读取任意类型的文件,不适合读取大文件。
ClassLoader cl=Demo5.class.getClassLoader(); InputStream is=cl.getResourceAsStream("cn/tf/servletContext/c.properties"); Properties prop=new Properties(); prop.load(is); System.out.println(prop.getProperty("key"));
ServletContext sc=getServletContext(); String path=sc.getRealPath("/WEB-INF/1.jpg");
OutputStream out=response.getOutputStream(); int len =-1; byte b[] =new byte[1024]; while((len=in.read(b))!=-1){ out.write(b,0,len); }四、告知浏览器去下载这个文件
response.setHeader("Content-Disposition", "attachment;filename=1.jpg"); response.setHeader("Content-Type", "application/octet-stream");
in.close(); out.close();
//文件下载 public class Demo6 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获得要下载的文件的真实路径 ServletContext sc=getServletContext(); String path=sc.getRealPath("/WEB-INF/1.jpg"); InputStream in=new FileInputStream(path); //告知浏览器去下载 response.setHeader("Content-Disposition", "attachment;filename=1.jpg"); response.setHeader("Content-Type", "application/octet-stream"); OutputStream out=response.getOutputStream(); int len =-1; byte b[] =new byte[1024]; while((len=in.read(b))!=-1){ out.write(b,0,len); } in.close(); out.close(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } }