Servlet(Server Applet),全称JavaServlet,未有中文译文。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。
Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。[百度百科]
** 如何使用servlet?
#1.编写一个继承与HttpServlet的java类
#2.重写doGet和doPost方法
#3.配置web.xml文件,配置servlet节点
MyFirstServlet.java
package com.ibatis01.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class MyFirstServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().append("my frist servlet"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
Web.xml
…… <servlet> <servlet-name>MyFirstServlet</servlet-name> <servlet-class>com.ibatis01.servlet.MyFirstServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>MyFirstServlet</servlet-name> <url-pattern>/MyFirst</url-pattern> </servlet-mapping> ……
运行结果:
** URL匹配
url-pattern 浏览器输入 精确匹配 /first http://localhost:8080/day/first /itcast/demo1 http://localhost:8080/day/itcast/demo1 模糊匹配 /* http://localhost:8080/day/任意路径 /itcast/* http://localhost:8080/day/itcast/任意路径 *.后缀名 http://localhost:8080/day/任意路径.do *.do *.action *.html(伪静态):并不是一个真的静态文件 默认路径[缺省路径,尽量少用] / http://localhost:8080/day |
注意:
#1.路径要不就是/开始,要不就是*开始,而且两种不能混合在一起用。
#2.当多个servlet被同时匹配,精确匹配优先
#3.默认路径:当路径匹配不到任何自定义的servlet的url路径,则去tomcat下找DefaultServlet到对象的应用下查找对应的静态文件,如果还找不到就返回404 not found[先找动态资源,再找静态文件]
** servlet的生命周期
构造方法:第一次访问servlet时候调用
init方法:创建完servlet时候调用
service方法:每次请求的时候调用
destroy方法:当servlet被销毁时候被调用
注意:
#1. service方法本来是用来分发调用doPost方法还是doGet方法,如果我们重写了service方法就不会调用doGet或者doPost方法。
#2. Init 方法有有参数和无参数两种方法,有参数的其实还是会调用无参的,所以servlet方法初始化代码写在无参数的init方法即可
#3. Servlet对象在tomcat中是单实例多线程的[servlet肯定用了多线程]
package com.ibatis01.servlet; import java.io.IOException; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; publicclass MyFirstServlet extends HttpServlet { /** * 构造方法 */ public MyFirstServlet() { System.out.println("1. 我被创建了......"); } /** * init方法 */ @Override public void init(ServletConfig config) throws ServletException { System.out.println("2. init方法被调用......"); } /** * service方法 */ @Override protected void service(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException { System.out.println("3. service方法被调用......"); } @Override public void destroy() { System.out.println("4. 调用destroy方法......"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("doGet 方法被调用......"); response.getWriter().append("my frist servlet"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("doPost 方法被调用......"); doGet(request, response); } }
** servlet的自动加载
在web.xml中加入load-on-startup即可[中间的数值越大优先级越低]
<servlet> <servlet-name>MyFirstServlet</servlet-name> <servlet-class>com.ibatis01.servlet.MyFirstServlet</servlet-class> <!-- 让servlet在服务器启动的时候就创建 --> <load-on-startup>1</load-on-startup> </servlet>
** servlet的线程安全问题
由于servlet是单实例多线程的,所以有可能引发多线程问题!
package com.ibatis01.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ThreadServlet extends HttpServlet { private int num=0; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { num++; Thread.sleep(2000); response.getWriter().append(this.toString()+"<br/>").append("num="+num); } catch (InterruptedException e) { e.printStackTrace(); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
结果是:[出现了想要的问题]
可以通过加锁来来解决问题
package com.ibatis01.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ThreadServlet extends HttpServlet { private int num = 0; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { synchronized (this) { try { num++; Thread.sleep(2000); response.getWriter().append(this.toString() + "<br/>").append("num=" + num); } catch (InterruptedException e) { e.printStackTrace(); } } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }