开发Servlet的三种方式
方式一:继承GenericServlet
public class FirstServlet extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("hello servlet");
}
}
注意:需要重写service方法
方式二:继承HttpServlet
public class SecondServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
注意:不需要重写service方法,因为HttpServlet类已经重写了service方法,其重写的service方法会根据请求方式的不同,自动跳转到doPost或者doGet方法,因此需要重写这两个方法。
方式一和方式二需要在web.xml文件中进行如下配置
<servlet>
<servlet-name>first</servlet-name>
<servlet-class>FirstServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>first</servlet-name>
<url-pattern>/first</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>second</servlet-name>
<servlet-class>SecondServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>second</servlet-name>
<url-pattern>/seccond</url-pattern>
</servlet-mapping>
方式三:使用@WebServlet注解
@WebServlet("/servlet3")
public class ThirdServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
Servlet的生命周期
顾名思义就是servlet从出生到死亡的整个过程。
servlet接口中制定了三个方法:
- init:默认情况下,在servlet第一次被访问之前调用。
servlet标签的loadOnStartup属性默认为负数,如果把该属性改成非负数,则当应用启动时,就调用 - service:当servlet被访问到的时候调用
- destroy:当应用被卸载,服务器关闭时调用
有什么样的的意义呢?
- 首先,生命周期函数本身的意义,对于init、destroy,如果你希望再servlet创建以及servlet被销毁的时候去做一些额外的事情,那么可以再init、destoy方法里面写对应的逻辑。
设置init load-on-startup非负数有什么样的意义呢?
- 比如说,当前servlet需要预先做一些运算,如果在第一次访问之前去执行,那么可能时间有点来不及,这个时候我就可以设置init方法随着应用的启动而执行,那么就有了更多的时间来运算。
url-pattern
一、url-pattern的优先级
servlet的url-pattern可能存在着相互覆盖的情况,最终tomcat会调用哪个servlet来处理该请求按如下规则:
- /开头的url-pattern的优先级高于*.后缀
- 对于都是/开头的url-pattern,匹配程度越高(匹配的越多),优先级也越高
二、url-pattern细节
- 一个servlet可以设置多个url-pattern吗?可以
- 多个servlet可以映射同一个url-pattern吗?不可以
- servlet的url-pattern有哪些写法呢? /xxx 和 *.后缀 ,其他全部都是非法的。
三、特殊的url-pattern
-
/*
当我们设置了/ *时,访问jsp页面以及访问静态资源页面均无法访问到 -
/
缺省servlet,专门用来接收那些没有任何servlet可以处理的请求。
Context域
用来实现多个servlet之间进行的数据共享
通过调用getServletContext()方法来获得唯一的context对象,在此对象上调用方法:
- setAttribute(key,value) 存数据
- getAttribute(key) 取数据
- removeAttribute(key) 删除数据
@WebServlet("/domain1")
public class DomainServlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = "zs";
ServletContext servletContext = getServletContext();
servletContext.setAttribute("username", name);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
@WebServlet("/domain2")
public class DomainServlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servlet = getServletContext();
String username = (String) servlet.getAttribute("username");
System.out.println(username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
在context对象上调用getRealPath()方法可以获得应用根目录的绝对路径